Ejemplo n.º 1
0
    def work(self, input_items, output_items):
        in0 = input_items[0]
        out = output_items[0]
        if self.avg == "True":
            avg = numpy.add(numpy.zeros(self.nData),numpy.zeros(self.nData)*1.j)
            for i in xrange(len(in0)):
		inp = in0[i]
                for a in numpy.arange(self.avgn):
                    low = a*self.nData
                    high = (a+1)*self.nData
                    avg = numpy.add(avg,inp[low:high])
                avg = avg/self.nData
                f, pw = sp.welch(avg,fs=self.fs,
                        window='hann',nperseg=self.nf,
                        noverlap=self.nf*self.noverlap,
                        scaling=self.scale,detrend=False)
		out[i] = pw
        if self.avg == "False":
            for i in xrange(len(in0)):
                x = in0[i]
            		# Uses the scipy.signal.welch method to average data
                f, pw = sp.welch(x,fs=self.fs,window='hann',
                        nperseg = self.nf,
                        noverlap=self.nf*self.noverlap,
                        scaling=self.scale,detrend=False)
		out[i] = pw
        return len(output_items[0])
        (output_items[0])
Ejemplo n.º 2
0
def estim_diff(percent=256):
    sound_counter=0
    res=np.empty(len(input_file_names))
    for i in range(res.shape[0]):
        input_rate,input_sig=wavfile.read(input_dir+'Segments/'+input_file_names[i])
        output_rate,output_sig=wavfile.read(output_dir+'Segments/'+output_file_names[i])
    
        input_sig=pcm2float(input_sig,'float32')
        output_sig=pcm2float(output_sig,'float32')
        
        min_size=np.min((input_sig[:,0].shape[0],output_sig[:,0].shape[0]))
        #print min_size,min_size*percent
        #S_inp=np.absolute(fft(input_sig[:min_size,0]-np.mean(input_sig[:min_size,0])))
        #S_out=np.absolute(fft(output_sig[:min_size,0]-np.mean(output_sig[:min_size,0])))
    
        t=time()
        nperseg=int(min_size*percent)-np.mod(int(min_size*percent),10)
        real_perc=float(float(nperseg)/int(min_size*percent))
        S_inp=signal.welch(input_sig[:min_size,0],nperseg=nperseg)[1]    
        S_out=signal.welch(output_sig[:min_size,0],nperseg=nperseg)[1]    
        #S_inp=ndim_welch(input_sig[:min_size,0][None,...],nperseg=int(min_size*percent))[1]    
        #S_out=ndim_welch(output_sig[:min_size,0][None,...],nperseg=int(min_size*percent))[1]    
        #print time()-t
        #print S_inp_1,S_inp_2
        res[sound_counter]=delta_estimator_3(S_out/S_inp,S_inp)-delta_estimator_3(S_inp/S_out,S_out)
        #out=float2pcm(output_sig,'int16')
        sound_counter+=1
    return real_perc,int(min_size*percent),res
Ejemplo n.º 3
0
def calculate_spectra(ts, samp, olap=0, nseg=3, wtype='tukey', norm=True):
    """
    ts = input time series
    samp = sampling rate in Hz
    olap = window overlap in %. 0 == Bartlett's method.
    nseg = number of segments to take for PSD estimation.
    wtype = window to use during calculation. see scipy.signal.get_window.
    norm = If true, normalizes spectra such that it's sum = 1.

    Calculates the spectra of an input time series using the specified window.
    Inspired by He, Biyu J in Neuron 2010 & J Neurosci 2011.
    """

    if olap < 0 or olap >= 100:
        print('INVALID: olap = ' + str(olap) + ', should be a % (1-99)')

    # calculate the length of each window, accounting for nseg and olap
    ntrs = ts.shape[-1]
    nperseg = ntrs / nseg * (1 + olap/100.0)

    while np.remainder(nperseg, 1) != 0:
        nseg = nseg - 1
        nperseg = ntrs / float(nseg) * (1 + olap/100.0)

    olap = olap * nperseg

    print('MSG: Calculating spectra using {} pts/window.'.format(nperseg))

    if wtype == 'tukey':
        window = tukeywin(nperseg, alpha=0.5)
        spectra = signal.welch(ts, fs=samp, window=window,
                                            noverlap=olap,
                                            nperseg=nperseg,
                                            return_onesided=True,
                                            scaling='spectrum')

    else:
        try:
            spectra = signal.welch(ts, fs=samp, window=wtype, 
                                                noverlap=olap,
                                                nperseg=nperseg,
                                                return_onesided=True,
                                                scaling='spectrum')

        except:
            print('Input window ' + str(wtype) + 'is invalid!')
            print('Using scipy default: hanning...')
            spectra = signal.welch(ts, fs=samp, noverlap=olap,
                                                nperseg=nperseg,
                                                return_onesided=True,
                                                scaling='spectrum')

    fs = spectra[0]
    pxx = spectra[1]

    # convert to %s (i.e., sum of pxx = 1)
    if norm == True:
        pxx = pxx / np.sum(pxx)

    return fs, pxx
Ejemplo n.º 4
0
 def test_nd_axis_0(self):
     x = np.arange(20, dtype=np.float64)+0.04
     x = x.reshape((10,2,1))
     f, p = welch(x, nperseg=10, axis=0)
     assert_array_equal(p.shape, (6,2,1))
     assert_array_almost_equal_nulp(p[:,0,0], p[:,1,0], 60)
     f0, p0 = welch(x[:,0,0], nperseg=10)
     assert_array_almost_equal_nulp(p0, p[:,1,0])
Ejemplo n.º 5
0
 def test_nd_axis_0(self):
     x = np.arange(20, dtype=np.float64) + 0.04
     x = x.reshape((10,2,1))
     f, p = welch(x, nperseg=10, axis=0)
     assert_array_equal(p.shape, (6,2,1))
     assert_allclose(p[:,0,0], p[:,1,0], atol=1e-13, rtol=1e-13)
     f0, p0 = welch(x[:,0,0], nperseg=10)
     assert_allclose(p0, p[:,1,0], atol=1e-13, rtol=1e-13)
Ejemplo n.º 6
0
 def test_nd_axis_m1(self):
     x = np.arange(20, dtype=np.float64) + 0.04
     x = x.reshape((2,1,10))
     f, p = welch(x, nperseg=10)
     assert_array_equal(p.shape, (2, 1, 6))
     assert_allclose(p[0,0,:], p[1,0,:], atol=1e-13, rtol=1e-13)
     f0, p0 = welch(x[0,0,:], nperseg=10)
     assert_allclose(p0[np.newaxis,:], p[1,:], atol=1e-13, rtol=1e-13)
Ejemplo n.º 7
0
 def test_empty_input(self):
     f, p = welch([])
     assert_array_equal(f.shape, (0,))
     assert_array_equal(p.shape, (0,))
     for shape in [(0,), (3,0), (0,5,2)]:
         f, p = welch(np.empty(shape))
         assert_array_equal(f.shape, shape)
         assert_array_equal(p.shape, shape)
Ejemplo n.º 8
0
 def test_window_external(self):
     x = np.zeros(16)
     x[0] = 1
     x[8] = 1
     f, p = welch(x, 10, 'hann', 8)
     win = signal.get_window('hann', 8)
     fe, pe = welch(x, 10, win, 8)
     assert_array_almost_equal_nulp(p, pe)
     assert_array_almost_equal_nulp(f, fe)
Ejemplo n.º 9
0
    def test_short_data(self):
        x = np.zeros(8)
        x[0] = 1
        with warnings.catch_warnings():
            warnings.simplefilter('ignore', UserWarning)
            f, p = welch(x)

        f1, p1 = welch(x, nperseg=8)
        assert_allclose(f, f1)
        assert_allclose(p, p1)
Ejemplo n.º 10
0
def transferFunction(sigin, sigout, fs, nfft=int(2e13), filtering=None,
                     limits=None):
    """
    Return frequencies and modulus of \
transfer function T(iw) = sigout(iw)/sigin(iw).

    Parameters
    ----------

    sigin, sigout : array_like
        Time series of measurement values for input and output

    fs : float
        Sampling frequency

    nfft : int, optional
        Length of the FFT used, if a zero padded FFT is desired. \
If None, the FFT length is nperseg. Defaults to None.

    filtering : float, optional
        If provided, apply a lowpass filter on sigin and sigout before \
computing fft (the default is None). Then filtering is the cutoff frequency \
as a fraction of the sampling rate (in (0, 0.5)).

    limits : (fmin, fmax), optional
        If provided, truncates the output between fmin and fmax \
(the default is None).

    Return
    ------

    f : list
        frequency point in Hertz.

    TF : list
        Modulus of transfer function.

    """
    if filtering is not None:
        sigin = lowpass(sigin, fc=filtering)
        sigout = lowpass(sigout, fc=filtering)
    import scipy.signal as sig
    f, Pxx_den1 = sig.welch(sigin, fs, nperseg=nfft, scaling='spectrum')
    f, Pxx_den2 = sig.welch(sigout, fs, nperseg=nfft, scaling='spectrum')
    TF = Pxx_den2/Pxx_den1
    if limits is None:
        fmin, fmax = 20., 20e3
    else:
        fmin, fmax = limits
    from numpy import nonzero
    nfmax = len(f) if fmax >= f[-1] else nonzero(f > fmax)[0][0]
    nfmin = nonzero(f > fmin)[0][0]
    f = f[nfmin:nfmax]
    TF = [el**0.5 for el in TF[nfmin:nfmax]]
    return f, TF
Ejemplo n.º 11
0
def test_filter_psd():
    """Test highpass filter with power spectral density."""
    a = np.sin(np.linspace(0, 4 * np.pi, 32))
    b = rs.randn(32) / 2
    y = a + b
    y_filt = glm.fsl_highpass_filter(y, 10)
    nt.assert_equal(y.shape, y_filt.shape)

    _, orig_d = signal.welch(y, nperseg=32)
    _, filt_d = signal.welch(y_filt, nperseg=32)

    nt.assert_greater(orig_d.sum(), filt_d.sum())
Ejemplo n.º 12
0
def welch_psd(Float, hpids, var, tz='z', hold='off'):
    """Compute power spectral density of some variable using Welch method.
    Variables are first interpolated onto a regular grid in either time or
    depth which can be specified using the tz optional argument. A time
    interval of 25 seconds is used and a depth interval of 4m."""

    dz = 4.
    dt = 25./86400.

    if tz == 'z':
        df = dz
        ivar = 'z'
        m = 1.
    elif tz == 't':
        df = dt
        ivar = 'UTC'
        m = 86400.
    else:
        raise RuntimeWarning("tz should be 't' or 'z'.")

    profiles = Float.get_profiles(hpids)
    if np.iterable(profiles):
        for i, profile in enumerate(profiles):
            f = getattr(profile, ivar)
            nans = np.isnan(f)
            f = np.unique(f[~nans])
            f = np.arange(f[0], f[-1], df)

            x = profile.interp(f, ivar, var)

            if hold == 'on':
                if i == 0:
                    plt.figure()
                freq, Pxx = sig.welch(x, 1./(m*df))
                plt.loglog(freq, Pxx)
            else:
                plt.figure()
                freq, Pxx = sig.welch(x, 1./(m*df))
                plt.loglog(freq, Pxx)

    else:
        f = getattr(profiles, ivar)
        nans = np.isnan(f)
        f = np.unique(f[~nans])

        f = np.arange(f[0], f[-1], df)

        x = profiles.interp(f, ivar, var)
        plt.figure()
        freq, Pxx = sig.welch(x, 1./(m*df))
        plt.loglog(freq, Pxx)
Ejemplo n.º 13
0
 def test_short_data(self):
     x = np.zeros(8)
     x[0] = 1
     #for string-like window, input signal length < nperseg value gives
     #UserWarning, sets nperseg to x.shape[-1]
     with suppress_warnings() as sup:
         sup.filter(UserWarning, "nperseg = 256 is greater than input length  = 8, using nperseg = 8")
         f, p = welch(x,window='hann')  # default nperseg
         f1, p1 = welch(x,window='hann', nperseg=256)  # user-specified nperseg
     f2, p2 = welch(x, nperseg=8)  # valid nperseg, doesn't give warning
     assert_allclose(f, f2)
     assert_allclose(p, p2)
     assert_allclose(f1, f2)
     assert_allclose(p1, p2)
Ejemplo n.º 14
0
 def test_short_data(self):
     x = np.zeros(8)
     x[0] = 1
     #for string-like window, input signal length < nperseg value gives
     #UserWarning, sets nperseg to x.shape[-1]
     with warnings.catch_warnings():
         warnings.simplefilter('ignore', UserWarning)
         f, p = welch(x,window='hann')  # default nperseg
         f1, p1 = welch(x,window='hann',
                        nperseg=256)  # user-specified nperseg
     f2, p2 = welch(x, nperseg=8)  # valid nperseg, doesn't give warning
     assert_allclose(f, f2)
     assert_allclose(p, p2)
     assert_allclose(f1, f2)
     assert_allclose(p1, p2)
Ejemplo n.º 15
0
    def display(self, data):
        """Make graphicsitem for spectrum figure.

        Parameters
        ----------
        data : ndarray
            1D vector containing the data only

        This function can be called by self.display_window (which reads the
        data for the selected channel) or by the mouse-events functions in
        traces (which read chunks of data from the user-made selection).
        """
        value = self.config.value
        self.scene = QGraphicsScene(value['x_min'], value['y_min'],
                                    value['x_max'] - value['x_min'],
                                    value['y_max'] - value['y_min'])
        self.idx_fig.setScene(self.scene)

        self.add_grid()
        self.resizeEvent(None)

        s_freq = self.parent.traces.data.s_freq
        f, Pxx = welch(data, fs=s_freq,
                       nperseg=int(min((s_freq, len(data)))))  # force int

        freq_limit = (value['x_min'] <= f) & (f <= value['x_max'])

        if self.config.value['log']:
            Pxx_to_plot = log(Pxx[freq_limit])
        else:
            Pxx_to_plot = Pxx[freq_limit]

        self.scene.addPath(Path(f[freq_limit], Pxx_to_plot),
                           QPen(QColor(LINE_COLOR), LINE_WIDTH))
Ejemplo n.º 16
0
def compute_NDSI(file, windowLength = 1024, anthrophony=[1000,2000], biophony=[2000,11000]):
    """
    Compute Normalized Difference Sound Index from an audio signal.
    This function compute an estimate power spectral density using Welch's method.

    Reference: Kasten, Eric P., Stuart H. Gage, Jordan Fox, and Wooyeong Joo. 2012. The Remote Environ- mental Assessment Laboratory's Acoustic Library: An Archive for Studying Soundscape Ecology. Ecological Informatics 12: 50-67.

    windowLength: the length of the window for the Welch's method.
    anthrophony: list of two values containing the minimum and maximum frequencies (in Hertz) for antrophony.
    biophony: list of two values containing the minimum and maximum frequencies (in Hertz) for biophony.

    Inspired by the seewave R package, the soundecology R package and the original matlab code from the authors.
    """

    #frequencies, pxx = signal.welch(file.sig_float, fs=file.sr, window='hamming', nperseg=windowLength, noverlap=windowLength/2, nfft=windowLength, detrend=False, return_onesided=True, scaling='density', axis=-1) # Estimate power spectral density using Welch's method
    # TODO change of detrend for apollo
    frequencies, pxx = signal.welch(file.sig_float, fs=file.sr, window='hamming', nperseg=windowLength, noverlap=windowLength/2, nfft=windowLength, detrend='constant', return_onesided=True, scaling='density', axis=-1) # Estimate power spectral density using Welch's method
    avgpow = pxx * frequencies[1] # use a rectangle approximation of the integral of the signal's power spectral density (PSD)
    #avgpow = avgpow / np.linalg.norm(avgpow, ord=2) # Normalization (doesn't change the NDSI values. Slightly differ from the matlab code).

    min_anthro_bin=np.argmin([abs(e - anthrophony[0]) for e in frequencies])  # min freq of anthrophony in samples (or bin) (closest bin)
    max_anthro_bin=np.argmin([abs(e - anthrophony[1]) for e in frequencies])  # max freq of anthrophony in samples (or bin)
    min_bio_bin=np.argmin([abs(e - biophony[0]) for e in frequencies])  # min freq of biophony in samples (or bin)
    max_bio_bin=np.argmin([abs(e - biophony[1]) for e in frequencies])  # max freq of biophony in samples (or bin)

    anthro = np.sum(avgpow[min_anthro_bin:max_anthro_bin])
    bio = np.sum(avgpow[min_bio_bin:max_bio_bin])

    ndsi = (bio - anthro) / (bio + anthro)
    return ndsi
def whelchMethod(data, Fs=200):
    f, pxx = signal.welch(data, fs=Fs, nperseg=1024)
    d = {'psd': pxx, 'freqs': f}
    df = pd.DataFrame(data=d)
    dfs = df.sort(['psd'], ascending=False)
    rows = dfs.iloc[:10]
    return rows['freqs'].mean()
Ejemplo n.º 18
0
def plot_psd_welch(data,fs,filename,flag):
    # Estimate PSD using Welchs method. Divides the data into overlapping segments, 
    #computing a modified periodogram for each segment and overlapping the periodograms
    
    plt.figure(figsize=(10,10))
    fig, (ax0,ax1) = plt.subplots(nrows=2)
    
    f, Pxx_den = signal.periodogram (data, fs)
    ax0.set_xlabel('frequency [Hz]')
    ax0.set_ylabel('periodogram')
    ax0.plot(f, Pxx_den)
    print "Periodogram"
    print "f is " , f
    print "Pxx_den is ", Pxx_den
     
    f2, Pxx_den2 = signal.welch(data, fs)
    ax1.set_ylabel('PSD [V**2/Hz]')

    print "Welch method "
    print "f2 is ", f2
    print "Pxx_den2 is" , Pxx_den2
    ax1.plot(f2, Pxx_den2)
    if flag==1:
       ax0.set_yscale('log')
       ax1.set_yscale('log')
       ax0.set_ylabel('periodogram (log scale)')
       ax1.set_ylabel('Welch\'s PSD [V**2/Hz] (log scale) ')
    plt.savefig(filename+'.pdf')
Ejemplo n.º 19
0
def plot_bin_riv():
    paths = [#'/Users/user/Desktop/nagrania_eeg/binriv/Kuba_14_06_16/',
            '/Users/user/Desktop/nagrania_eeg/binriv/Karen_14_06_16/',
            '/Users/user/Desktop/nagrania_eeg/binriv/Ania_14_06_16/'
            ]
    for path in paths:
        recording = loading.Read_edf.Combine_EDF_XML(path,0,70)
        
        
        f, Pxx_den = signal.welch(recording['EEG P4'], fs = 498, nperseg=512)
        
        plt.figure()
        plt.plot(f, Pxx_den)
        
        
        epochs_before_info = {"response_changed": [ 498*5, 0] }
        
        epochs_before = prep.Epochs.Make_Epochs_for_Channels(recording, ['EEG P4'], epochs_before_info)['EEG P4']
        
        epochs_after_info = {"response_changed": [0, 498*5] }
        
        epochs_after = prep.Epochs.Make_Epochs_for_Channels(recording, ['EEG P4'], epochs_after_info)['EEG P4']
        
        epochs = {}
        epochs['P4'] = {'before_switch':epochs_before['response_changed'], 'after_switch': epochs_after['response_changed']}
        
        power_density= analysis.Explore.PlotPowerSpectrum(epochs['P4'], exact_sr =498, mode = 'welch', name = path, freq_min = 0, freq_max = 100)
Ejemplo n.º 20
0
def Power_Spectrum(ts, fs, dt):

    """Compute power spectral density (using psd welch)"""
    "ts: time series of measurement values"
    "fs: sampling frequency"
    "dt: detrend = None/'linear'/'constant'"
    "scal = 'density', normalized with units of V**2/hz"
    "scal = 'spectrum', units of V**2"

    ts[np.isnan(ts) == True] = nanmean(ts)  # Gapfill the missing value
    nwindow = 9  # Number of windows to smooth data
    length = math.floor(len(ts) / nwindow)  # Length calculated by deviding the window
    nwindow_fl = math.floor(log2(length))  # Number of windows with floor window length
    window = int(2 ** nwindow_fl)  # segment_length

    ############################### nfft: Number of DFT points ###############################
    # The default nfft is the greater of 256 or the next power of 2 greater than the length of the segments.
    # The relation between segment length and the Number of DFT points: segment_length <= nfft
    # If nfft is greater than the segment length, the data is zero-padded. If nfft is less than the segment length, the segment is wrapped using datawrap to make the length equal to nfft
    ##########################################################################################

    ###############################   welch's method for PSD   ###############################
    # MATLAB function: pwelch(ts, segment_length, Number of overlapped window noverlap, Number of DFT points, fs,'onesided')
    # scipy method: pwelch(ts, fs, nperseg, noverlap, nfft, detrend, scaling)
    ##########################################################################################

    f, Pxx_den = signal.welch(ts, fs, nperseg=window, detrend=dt)

    return [f, Pxx_den]
Ejemplo n.º 21
0
 def test_window_external(self):
     x = np.zeros(16)
     x[0] = 1
     x[8] = 1
     f, p = welch(x, 10, 'hann', nperseg=8)
     win = signal.get_window('hann', 8)
     fe, pe = welch(x, 10, win, nperseg=None)
     assert_array_almost_equal_nulp(p, pe)
     assert_array_almost_equal_nulp(f, fe)
     assert_array_equal(fe.shape, (5,))  # because win length used as nperseg
     assert_array_equal(pe.shape, (5,))
     assert_raises(ValueError, welch, x,
                   10, win, nperseg=4)  # because nperseg != win.shape[-1]
     win_err = signal.get_window('hann', 32)
     assert_raises(ValueError, welch, x,
                   10, win_err, nperseg=None)  # win longer than signal
Ejemplo n.º 22
0
    def test_axis_rolling(self):
        np.random.seed(1234)

        x_flat = np.random.randn(1024)
        _, p_flat = welch(x_flat)

        for a in range(3):
            newshape = [1,]*3
            newshape[a] = -1
            x = x_flat.reshape(newshape)

            _, p_plus = welch(x, axis=a)  # Positive axis index
            _, p_minus = welch(x, axis=a-x.ndim)  # Negative axis index

            assert_equal(p_flat, p_plus.squeeze(), err_msg=a)
            assert_equal(p_flat, p_minus.squeeze(), err_msg=a-x.ndim)
Ejemplo n.º 23
0
 def test_nondefault_noverlap(self):
     x = np.zeros(64)
     x[::8] = 1
     f, p = welch(x, nperseg=16, noverlap=4)
     q = np.array([0, 1./12., 1./3., 1./5., 1./3., 1./5., 1./3., 1./5.,
                   1./6.])
     assert_allclose(p, q, atol=1e-12)
Ejemplo n.º 24
0
 def test_integer_onesided_even(self):
     x = np.zeros(16, dtype=np.int)
     x[0] = 1
     x[8] = 1
     f, p = welch(x, nperseg=8)
     assert_allclose(f, np.linspace(0, 0.5, 5))
     assert_allclose(p, np.array([0.08333333, 0.15277778, 0.22222222, 0.22222222, 0.11111111]))
Ejemplo n.º 25
0
 def test_detrend_external_nd_0(self):
     x = np.arange(20, dtype=np.float64) + 0.04
     x = x.reshape((2,1,10))
     x = np.rollaxis(x, 2, 0)
     f, p = welch(x, nperseg=10, axis=0,
                  detrend=lambda seg: signal.detrend(seg, axis=0, type='l'))
     assert_allclose(p, np.zeros_like(p), atol=1e-15)
def dofft(sig,samplefrq,nperseg=512,detrend='constant'):
    """
    Estimate power spectral density using Welch's method. For more informations
    on the Welch's method implemented in python, visit:

    http://docs.scipy.org/doc/scipy-dev/reference/generated/scipy.signal.welch.html

    Example:
        >>> frq,psd = dofft(sig=mySignal, samplefrq=mySampleFrq)

    Arguments:
        * sig: [numpy.array] signal
        * samplefrq: [int or float] sample frequency

    Returns:
        * frq: [numpy.array]frequencies
        * psd: [numpy.array]amplitudes
    """
    # old crap...
    #siglength = sig.shape[0]
    #NFFT = nextpow2(siglength)
    ##    NFFT = nextpow2(sig.shape(-1,)[0])
    #amp = spfft.fft(sig.reshape(-1,),NFFT)/siglength
    #frq = samplefrq/2*np.linspace(0,1,NFFT/2+1)
    ##    frq = spfft.fftfreq(siglength, (samplefrq)**-1)
    ##    frq = frq[:NFFT/2+1]
    #amp = 2*abs(amp[:NFFT/2+1])
    #return frq,amp

    frq, psd = spsig.welch(sig,fs=samplefrq, window='hanning', noverlap=None, nperseg=nperseg, return_onesided=True, scaling='density', axis=-1,detrend=detrend)
    return frq, psd
Ejemplo n.º 27
0
 def test_integer_onesided_odd(self):
     x = np.zeros(16, dtype=np.int)
     x[0] = 1
     x[8] = 1
     f, p = welch(x, nperseg=9)
     assert_allclose(f, np.arange(5.0) / 9.0)
     assert_allclose(p, np.array([0.15958226, 0.24193954, 0.24145223, 0.24100919, 0.12188675]))
    def process_samples(self):
        rs = self.scanner.sample_rate
        fc = self.center_frequency

        samples = self.raw.flatten()

        overlap_ratio = self.scanner.sampling_config.sweep_overlap_ratio

        win = get_window(self.scanner.sampling_config.window_type, NPERSEG)
        freqs, Pxx = welch(samples, fs=rs, window=win,
            nperseg=NPERSEG, scaling='density', return_onesided=False)

        iPxx = np.fft.irfft(Pxx)
        iPxx = self.translate_freq(iPxx, fc, rs)
        Pxx = np.abs(np.fft.rfft(iPxx.real))

        freqs, Pxx = sort_psd(freqs, Pxx)
        f_ix = np.append(np.nonzero(freqs<-0.25e6), np.nonzero(freqs>0.25e6))
        freqs = freqs[f_ix]
        Pxx = Pxx[f_ix]

        freqs += fc
        freqs /= 1e6

        self.powers = Pxx
        if not np.array_equal(freqs, self.frequencies):
            print('freq not equal: %s, %s' % (self.frequencies.size, freqs.size))
            self.frequencies = freqs

        self.collection.on_sample_set_processed(self)
        self.complete.set()
Ejemplo n.º 29
0
    def PltUp(n):
        nonlocal DataPlot, SBInAmpF, FreqBand
        Block = True
        
        while True:
            try:
                Data = SoundQueue.get(block=Block)
                Data = Data * SBInAmpF
                
#                HWindow = signal.hanning(len(Data)//(Rate/1000))
                F, PxxSp = signal.welch(Data, Rate, nperseg=64, noverlap=0, 
                                        scaling='density')
                
#                Start = np.where(F > FreqBand[0])[0][0]-1
#                End = np.where(F > FreqBand[1])[0][0]-1
                BinSize = F[1] - F[0]
                RMS = sum(PxxSp * BinSize)**0.5
                dB = 20*(math.log(RMS/MicSens_VPa, 10)) + 94
                
                
            except Empty:
                break
#            Shift = len(Data)
#            DataPlot = np.roll(DataPlot, -Shift, axis=0)
#            DataPlot[-Shift:, 0] = Data
            Block = False
        
        for Col, Line in enumerate(Lines):
            print(dB, max(PxxSp))
            Line.set_xdata(F)
            Line.set_ydata(PxxSp)
        
        return(Lines)
Ejemplo n.º 30
0
def _efficient_welch(data, sfreq):
    """Calls scipy.signal.welch with parameters optimized for greatest speed
    at the expense of precision. The window is set to ~10 seconds and windows
    are non-overlapping.

    Parameters
    ----------
    data : array, shape (..., n_samples)
        The timeseries to estimate signal power for. The last dimension
        is assumed to be time.
    sfreq : float
        The sample rate of the timeseries.

    Returns
    -------
    fs : array of float
        The frequencies for which the power spectra was calculated.
    ps : array, shape (..., frequencies)
        The power spectra for each timeseries.
    """
    from scipy.signal import welch
    nperseg = min(data.shape[-1],
                  2 ** int(np.log2(10 * sfreq) + 1))  # next power of 2

    return welch(data, sfreq, nperseg=nperseg, noverlap=0, axis=-1)
Ejemplo n.º 31
0
def PSD_using_scipy(ampl, fs):
    return signal.welch(ampl, fs, nperseg=1024, scaling= 'spectrum')
Ejemplo n.º 32
0
    #Read chunks
    for i in range(1):
        y = x.read(round(RATE * SAMPLE_TIME))
        w = 0
        while w + 4 <= len(y):
            (l, r) = struct.unpack('<2h', y[w:w + 4])  # left & right samples
            lx.append(l)
            w += 4

    x.stop_stream()

    # MIDI note off
    os.write(f, b'\x80' + struct.pack('B', nn) + b'\x7f')
    time.sleep(0.5)

    fr, pw = signal.welch(lx, RATE)
    b_1.append(pw)

plt.figure()

idx_0 = 0

for j in range(2):
    if j != idx_0:
        c = []
        for k in range(len(b_1[0])):
            c.append(10. * numpy.log10(b_1[j][k] / b_1[idx_0][k]))
        plt.plot(fr, c, label='{0}'.format(j))
plt.xlim(0, 5000)  # Frequency range to show
plt.legend(loc='lower right')
Ejemplo n.º 33
0
 def test_detrend_external(self):
     x = np.arange(10, dtype=np.float64) + 0.04
     f, p = welch(x,
                  nperseg=10,
                  detrend=lambda seg: signal.detrend(seg, type='l'))
     assert_allclose(p, np.zeros_like(p), atol=1e-15)
Ejemplo n.º 34
0
def psd_calc_other_methods(df, prm: Mapping[str, Any]):
    ## scipy
    windows = signal.windows.dpss(180000, 2.5, Kmax=9, norm=2)
    signal.spectrogram

    ## Welch
    nperseg = 1024 * 8
    freqs, psd_Ve = signal.welch(df.Ve, prm['fs'], nperseg=nperseg)
    freqs, psd_Vn = signal.welch(df.Vn, prm['fs'], nperseg=nperseg)

    ## use Spectrum module
    from spectrum import dpss

    def pmtm(x, eigenvalues, tapers, n_fft=None, method='adapt'):
        """Multitapering spectral estimation

        :param array x: the data
        :param eigenvalues: the window concentrations (eigenvalues)
        :param tapers: the matrix containing the tapering windows
        :param str method: set how the eigenvalues are used. Must be
            in ['unity', 'adapt', 'eigen']
        :return: Sk (each complex), weights, eigenvalues

        Usually in spectral estimation the mean to reduce bias is to use tapering
        window. In order to reduce variance we need to average different spectrum.
        The problem is that we have only one set of data. Thus we need to
        decompose a set into several segments. Such method are well-known: simple
        daniell's periodogram, Welch's method and so on. The drawback of such
        methods is a loss of resolution since the segments used to compute the
        spectrum are smaller than the data set.
        The interest of multitapering method is to keep a good resolution while
        reducing bias and variance.

        How does it work? First we compute different simple periodogram with the
        whole data set (to keep good resolution) but each periodgram is computed
        with a differenttapering windows. Then, we average all these spectrum.
        To avoid redundancy and bias due to the tapers mtm use special tapers.

        from spectrum import data_cosine, dpss, pmtm
        data = data_cosine(N=2048, A=0.1, sampling=1024, freq=200)
        [tapers, eigen] = dpss(2048, 2.5, 4)
        res = pmtm(data, eigenvalues=eigen, tapers=tapers, show=False)

        .. versionchanged:: 0.6.2a
        The most of spectrum.pmtm original code is to calc PSD but it is not returns so here we return it
        + Removed redandand functionality (calling semilogy plot and that what included in spectrum.dpss)
        """
        assert method in ['adapt', 'eigen', 'unity']

        N = len(x)
        if eigenvalues is not None and tapers is not None:
            eig = eigenvalues[:]
            tapers = tapers[:]
        else:
            raise ValueError(
                "if eigenvalues provided, v must be provided as well and viceversa."
            )
        nwin = len(eig)  # length of the eigen values vector to be used later

        if n_fft is None:
            n_fft = max(256, 2**np.ceil(np.log2(N)).astype('int'))

        Sk_complex = np.fft.fft(tapers.transpose() * x, n_fft)

        # if nfft < N, cut otherwise add zero.
        Sk = (Sk_complex * Sk_complex.conj()).real  # abs() ** 2
        if method in ['eigen', 'unity']:
            if method == 'unity':
                weights = np.ones((nwin, 1))
            elif method == 'eigen':
                # The S_k spectrum can be weighted by the eigenvalues, as in Park et al.
                weights = np.array(
                    [_x / float(i + 1) for i, _x in enumerate(eig)])
                weights = weights.reshape(nwin, 1)
                Sk = np.mean(Sk * weights, axis=0)
        elif method == 'adapt':
            # This version uses the equations from [2] (P&W pp 368-370).
            Sk = Sk.transpose()
            S = Sk[:, :2].mean()  # Initial spectrum estimate

            # Set tolerance for acceptance of spectral estimate:
            sig2 = np.dot(x, x) / float(N)
            tol = 0.0005 * sig2 / float(n_fft)
            a = sig2 * (1 - eig)

            # Wrap the data modulo nfft if N > nfft
            S = S.reshape(n_fft, 1)
            for i in range(
                    100):  # converges very quickly but for safety; set i<100
                # calculate weights
                b1 = np.multiply(S, np.ones((1, nwin)))
                b2 = np.multiply(S, eig.transpose()) + np.ones(
                    (n_fft, 1)) * a.transpose()
                b = b1 / b2

                # calculate new spectral estimate
                weights = (b**2) * (np.ones((n_fft, 1)) * eig.transpose())
                S1 = ((weights * Sk).sum(axis=1, keepdims=True) /
                      weights.sum(axis=1, keepdims=True))
                S, S1 = S1, S
                if np.abs(S - S1).sum() / n_fft < tol:
                    break
            Sk = (weights * Sk).mean(axis=1)

        if np.isrealobj(
                x
        ):  # Double to account for the energy in the negative frequencies
            if prm['n_fft'] % 2 == 0:
                Sk = 2 * Sk[:int(prm['n_fft'] / 2 + 1)]
            else:
                Sk = 2 * Sk[:int((prm['n_fft'] + 1) / 2)]

        return Sk_complex, Sk, weights

    prm['dpss_sp'], prm['eigvals_sp'] = dpss(prm['n_fft'], 3.5)
    sk_complex_Ve, sk_Ve_, weights_Ve = pmtm(
        df.Ve.values, prm['eigvals_sp'], prm['dpss_sp'])  # n_fft=prm['n_fft']
    sk_complex_Vn, sk_Vn_, weights_Vn = pmtm(df.Vn.values, prm['eigvals_sp'],
                                             prm['dpss_sp'])
    # Convert Power Spectrum to Power Spectral Density
    record_time_length = prm['length'] * prm['dt']
    sk_Ve = sk_Ve_ / record_time_length
    sk_Vn = sk_Vn_ / record_time_length
Ejemplo n.º 35
0
    if (Heart_rate[i] < Heart_rate_DOWN_Val):
        count += 1
Heart_rate_DOWN = count / Heart_rate.size * 100
ECG_features = [IBI_MEAN]
ECG_features.append(IBI_STD)
ECG_features.append(IBI_SKEW)
ECG_features.append(IBI_KURTOSIS)
ECG_features.append(IBI_UP)
ECG_features.append(IBI_DOWN)
ECG_features.append(Heart_rate_MEAN)
ECG_features.append(Heart_rate_STD)
ECG_features.append(Heart_rate_SKEW)
ECG_features.append(Heart_rate_KURTOSIS)
ECG_features.append(Heart_rate_UP)
ECG_features.append(Heart_rate_DOWN)
f_dash, Pxx_den = signal.welch(sig, fs=sampling_freq, nfft=100000)
Pxx_den = list(Pxx_den)
for i in range(5):
    ECG_features.append(Pxx_den[i])
for i in range(0, 255, 24):
    ECG_features.append(Pxx_den[i])
with open(fnamex, 'w', newline='') as file:
    writer = csv.writer(file)
    writer.writerow([
        ECG_features[0], ECG_features[1], ECG_features[2], ECG_features[3],
        ECG_features[4], ECG_features[5], ECG_features[6], ECG_features[7],
        ECG_features[8], ECG_features[9], ECG_features[10], ECG_features[11],
        ECG_features[12], ECG_features[13], ECG_features[14], ECG_features[15],
        ECG_features[16], ECG_features[17], ECG_features[18], ECG_features[19],
        ECG_features[20], ECG_features[21], ECG_features[22], ECG_features[23],
        ECG_features[24], ECG_features[25], ECG_features[26], ECG_features[27],
Ejemplo n.º 36
0
def welch_psd(nni=None,
              rpeaks=None,
              fbands=None,
              nfft=2**12,
              detrend=True,
              window='hamming',
              show=True,
              show_param=True,
              legend=True,
              mode='normal'):
    """Computes a Power Spectral Density (PSD) estimation from the NNI series using the Welch’s method
	and computes all frequency domain parameters from this PSD according to the specified frequency bands.

	References: [Electrophysiology1996], [Umberto2017], [Welch2017]
	Docs:		https://pyhrv.readthedocs.io/en/latest kwa/_pages/api/frequency.html#welch-s-method-welch-psd

	Parameters
	----------
	nni : array
		NN-Intervals in [ms] or [s]
	rpeaks : array
		R-peak locations 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.000Hz, 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 FFT result (default: 2**12)
	detrend : bool optional
		If True, detrend NNI series by subtracting the mean NNI (default: True)
	window : scipy window function, optional
		Window function used for PSD estimation (default: 'hamming')
	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 Welch's method's PSD estimation (see list and keys below)

	Returned Parameters & Keys
	--------------------------
	..	Peak frequencies of all frequency bands in [Hz] (key: 'fft_peak')
	..	Absolute powers of all frequency bands in [ms^2][(key: 'fft_abs')
	..	Relative powers of all frequency bands [%] (key: 'fft_rel')
	..	Logarithmic powers of all frequency bands [-] (key: 'fft_log')
	..	Normalized powers of all frequency bands [-] (key: 'fft_norms')
	..	LF/HF ratio [-] (key: 'fft_ratio')
	..	Total power over all frequency bands in [ms^2] (key: 'fft_total')
	..	Interpolation method used for NNI interpolation (key: 'fft_interpolation')
	..	Resampling frequency used for NNI interpolation (key: 'fft_resampling_frequency')
	..	Spectral window used for PSD estimation of the Welch's method (key: 'fft_spectral_window)'

	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 (fft_results = ReturnTuple object returned by
		this function):

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

			Using VLF, LF and HF frequency bands:
				fft_results['fft_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.
    s
	"""
    # Check input values
    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)

    # Subtract mean value from each sample for surpression of DC-offsets
    if detrend:
        nn_interpol = nn_interpol - np.mean(nn_interpol)

    # Adapt 'nperseg' according to the total duration of the NNI series (5min threshold = 300000ms)
    if t.max() < 300000:
        nperseg = nfft
    else:
        nperseg = 300

    # Compute power spectral density estimation (where the magic happens)
    frequencies, powers = welch(x=nn_interpol,
                                fs=fs,
                                window=window,
                                nperseg=nperseg,
                                nfft=nfft,
                                scaling='density')

    # Metadata
    args = (nfft, window, fs, 'cubic')
    names = (
        'fft_nfft',
        'fft_window',
        'fft_resampling_frequency',
        'fft_interpolation',
    )
    meta = utils.ReturnTuple(args, names)

    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('fft', frequencies, powers,
                                             fbands)

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

        # Output
        return tools.join_tuples(params, figure, meta)

    # 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('fft', 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('fft', frequencies, powers,
                                             fbands)

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

        # Output
        return tools.join_tuples(params, figure,
                                 meta), frequencies, (powers / 10**6)
        #Set montage (3d electrode location)
        raw = raw.set_montage('standard_1020')

        #Create events every w1 seconds
        sf = 250
        w1 = 2
        events_array = createEvenlySpaceEvents(rawArray.shape[1], w1, sf)
        #Create Epochs
        epochs = mne.Epochs(raw, events_array, tmin=-(w1 / 2 - 0.02 * w1), tmax=(w1 / 2 - 0.02 * w1))

        #Get data as numpy array
        epochsArray = epochs.get_data(picks=['eeg'])
        numbOfEpochs = epochsArray.shape[0]

        win = int(1.8 * sf)  # Window size is set to 4 seconds
        freqs, psd = welch(epochsArray, sf, nperseg=win, axis=-1)

        # Calculate the bandpower on 3-D PSD array
        bands = [(0.5, 4, 'Delta'), (4, 8, 'Theta'), (8, 12, 'Alpha'),
                 (12, 16, 'Sigma'), (16, 30, 'Beta')]
        bandpower = yasa.bandpower_from_psd_ndarray(psd, freqs, bands)

        bandpower = bandpower.transpose([1,0,2]).reshape((numbOfEpochs,-1))

        #Shape should be (#ofEpochs, #OfChannels*#ofbands)
        print(bandpower.shape)

        with open(dstPath / file.with_suffix(".pickle").name, 'wb') as outF:
            pickle.dump(bandpower,outF)

        x = 0
Ejemplo n.º 38
0
import audio_functions
import numpy as np
from scipy import signal
import matplotlib.pyplot as plt

duration = 5.0
fs = 44100
buffer_length = 1024

input('Press Enter when ready to record a sample')
samples = audio_functions.record(duration, fs, buffer_length)
print('Finished recording, now plotting recorded audio')  #
print(samples)

f, psd = signal.welch(samples, fs, nperseg=1024)
Ejemplo n.º 39
0
    def getSpectra(self, FIRST_SAMPLE, LAST_SAMPLE, *args):
        if 'mod' in args:
            print('\nplotting spectra for MODULATED units and stimulus')
            spikes = self.unitsXspikesLst_mod
        elif not 'mod' in args:
            print('\nplotting spectra for units and stimulus')
            spikes = self.unitsXspikesLst

        totalStimDurationSecs = LAST_SAMPLE - FIRST_SAMPLE  ### in secs
        if totalStimDurationSecs > 10:  ## stimulus duration must be longer than 10 secs to plot it
            plotSine = True
        else:
            plotSine = False
            FIRST_SAMPLE = 0
            LAST_SAMPLE = np.max(np.max(spikes))
            totalStimDurationSecs = LAST_SAMPLE - FIRST_SAMPLE  ### in secs

        ### neuron's bin'd sample rate
        numBins, remainderSecs = np.divmod(
            totalStimDurationSecs, BIN_SIZE_SEC
        )  ### totalStimDuration is from 0 to the last spike time if no TTLs are present
        bins = np.linspace(FIRST_SAMPLE,
                           FIRST_SAMPLE +
                           round(float(numBins) * float(BIN_SIZE_SEC)),
                           int(numBins),
                           endpoint=True)
        binSampleRate = 1. / np.mean(np.diff(bins))

        print('binSampleRate = {0}'.format(binSampleRate))

        ### Welch PSD
        ### sine stimulus
        if plotSine == True:
            ### sine stim's bin'd sample rate
            try:
                sineStimSampleRate = self.sine_vals.shape[
                    0] / totalStimDurationSecs
            except:
                sys.exit(
                    '\n\nERROR: You probably need to uncomment data.reconstructSineFromTTLs(TTL_values, TTL_times) below to get the TTLs...\n\n'
                )
            print('sineStimSampleRate = {0}'.format(sineStimSampleRate))
            welchFreqs_sine, Pxx_den = welch(
                self.sine_vals,
                nperseg=sineStimSampleRate * 100,
                fs=sineStimSampleRate
            )  ######## TO DO: Fix the sample rate }{ time units

            ### set up figure assuming the sine is present
            NUM_ROWS = 3
            NUM_COLUMNS = 1
            ### gridspec.GridSpec(NUM_ROWS,NUM_COLUMNS) # state-based versions for subplot
            ### plt.subplot(611) ### doesn't require gridspec but is kinda clunky for dynamic changes
            FIG_SIZE = (NUM_ROWS, NUM_COLUMNS)
            fig = plt.figure(figsize=FIG_SIZE)
            rowPosition = 0
            columnPosition = 0

            ### sine stimulus
            ax1 = plt.subplot2grid((NUM_ROWS, NUM_COLUMNS),
                                   (rowPosition, columnPosition))
            rowPosition += 1
            ax1.set_title('sine stimulus Welch PSD')
            ax1.set_xlabel('frequency [Hz]')
            ax1.set_ylabel('PSD [V**2/Hz?]')
            ax1.semilogy(welchFreqs_sine, Pxx_den, '-o')
            ax1.set_xlim(0, MAX_FREQ_PLOTTED)

        elif plotSine == False:
            print(
                'sine stimulus sample rate calculation failed (this is expected if there are no TTLs for this recording)'
            )
            ### set up the figure if there's no sine stimulus
            NUM_ROWS = 2
            NUM_COLUMNS = 1
            FIG_SIZE = (NUM_ROWS, NUM_COLUMNS)
            fig = plt.figure(figsize=FIG_SIZE)
            rowPosition = 0
            columnPosition = 0

        ### neurons
        ax2 = plt.subplot2grid((NUM_ROWS, NUM_COLUMNS),
                               (rowPosition, columnPosition))
        rowPosition += 1
        ax2.set_title('neurons\' Welch PSD (sci py ver)')
        ax2.set_xlabel('frequency [Hz]')
        ax2.set_ylabel('PSD [V**2/Hz?]')
        ax2.set_xlim(0, MAX_FREQ_PLOTTED)

        ax3 = plt.subplot2grid((NUM_ROWS, NUM_COLUMNS),
                               (rowPosition, columnPosition))
        rowPosition += 1
        ax3.set_title('neurons\' PSD (matplotlib ver)')
        ax3.set_xlim(0, MAX_FREQ_PLOTTED)

        #        ax4 = plt.subplot2grid((NUM_ROWS, NUM_COLUMNS), (rowPosition,columnPosition))
        #        rowPosition += 1
        #        ax4.set_title('neurons\' magnitude spectrum')
        #        ax4.set_xlim(0, MAX_FREQ_PLOTTED)

        #        ax5 = plt.subplot2grid((NUM_ROWS, NUM_COLUMNS), (rowPosition,columnPosition))
        #        rowPosition += 1
        #        ax5.set_title('neurons\' spectrogram')
        #        ax5.set_ylabel('Freq in Hz')
        #        ax5.set_xlabel('time in Secs')
        #        ax5.set_ylim(0,100)

        if UNITS_PLOTTED == [0, 0]:
            firstUnit = 0
            lastUnit = len(spikes) - 1  ### return to original after debugging
        else:
            firstUnit = UNITS_PLOTTED[0]
            lastUnit = UNITS_PLOTTED[-1]

        unitXfreqLst = []
        for unit in range(firstUnit, lastUnit + 1):
            t = "unit: {0}".format(unit)
            print(t)

            #            unit_hist, binEdges = np.histogram(spikes[unit], bins, (FIRST_SAMPLE, LAST_SAMPLE))
            unit_hist, binEdges = np.histogram(spikes[unit], bins)

            ### Welch PSD
            welchFreqs_neuron, Pxx_den = welch(
                unit_hist,
                fs=binSampleRate,  # sample rate
                window='hanning',  # apply a Hanning window before taking the DFT
                nperseg=self.sampleRate /
                10,  # number of samples to include in the sliding window
                detrend='constant'
            )  ################################################################################## is detrending appropriate?
            unitXfreqLst.append([welchFreqs_neuron, Pxx_den])

            ax2.semilogy(welchFreqs_neuron, Pxx_den, '-o', label=str(unit))
#            ax2.plot(welchFreqs_neuron,Pxx_den, '-o')
#            ax2.legend(['unit: {0}'.format(unit)])

### Welch PSD
#            ax3.psd(unit_hist, binSampleRate, pad_to=1024, detrend = 'mean')
#            ax3.psd(unit_hist, Fs= binSampleRate, NFFT= self.sampleRate, marker='o')  ### <-- probably closer to working

### magnitude spectrum
#            ax4.magnitude_spectrum(unit_hist, Fs = binSampleRate, scale = 'dB', marker = 'o')
#            try:
#                ax4.magnitude_spectrum(unit_hist, Fs = binSampleRate, marker = 'o')
#            except:
#                print('magnitude spectrum threw an error for unit {0};\n error: noverlap must be less than n'.format(unit))

### Spectrogram
#                Pxx, freqs, bins, im = ax5.specgram(spikes[unit], Fs=self.sampleRate, noverlap=100)
#                Pxx, freqs, bins, im = ax5.specgram(unit_hist, Fs=self.sampleRate, noverlap=100)
#            Pxx, freqs, bins, im = ax5.specgram(unit_hist, Fs= binSampleRate) ### TO DO: FIX RUNTIME WARNING: DIVIDE BY ZERO

#        fig.colorbar(im).set_label('Intensity [dB]')
#        fig.tight_layout()
        fig.subplots_adjust(hspace=1.0)
        fig.set_size_inches(w=15, h=8)
        fig_name = 'plot.png'
        fig.savefig(fig_name)

        if 'plot' in args: plt.show()

        ### TO DO: save plots to output dir
        if 'mod' in args:
            self.allPSDsLst_mod = unitXfreqLst
        else:
            self.unitXfreqLst = unitXfreqLst
        return unitXfreqLst
Ejemplo n.º 40
0
    envelope_oi = envelope(outputi)

    # Noisy echoes
    N = 0.5
    noise = np.random.normal(0, N, t.size)
    noisy_echoes = echoes + noise

    # Matched filter output both echoes with noise
    noisy_output = np.convolve(matched, noisy_echoes)*Ts
    noisy_output = noisy_output[:t.size]

    # Envelope of matched filter output with noise
    noisy_envelope_o = envelope(noisy_output)

    # Noise FFT
    Nfreq, Nabs = welch(noise, 1/Ts, nperseg=noise.size)

    # Plot of Signal
    # Plot of FFT
    plt.figure()
    plt.subplot(3, 1, 1)
    plt.plot(t[t<1.5*tau], signal[t<1.5*tau])
    plt.plot(tpulse, phase, 'r--', lw=1)
    plt.plot(tpulse[tpulse<=tphase*l], phase[tpulse<=tphase*l], 'r', lw=1)
    plt.title("Binary Pulses")
    plt.xlabel("time [us]")
    plt.ylabel("amplitude")
    plt.legend(["signal", "baker code"], loc='upper right')
    plt.grid(True)
    plt.subplot(3, 1, 2)
    plt.plot(freq[freq<2*f], Sabs[freq<2*f])
Ejemplo n.º 41
0
 def test_detrend_linear(self):
     x = np.arange(10, dtype=np.float64) + 0.04
     f, p = welch(x, nperseg=10, detrend='linear')
     assert_allclose(p, np.zeros_like(p), atol=1e-15)
Ejemplo n.º 42
0
def frequency_features(ts, RR, sampling_rate=4.0):
    """Compute frequency-domain HRV features.
    
    Parameters
    ----------
    ts : array
        Input time reference.
    RR : array
        Input RR signal.
    sampling_rate : int, float, optional
        Sampling frequency for resampled signal.
    
    Returns
    -------
    its : array
        Interpolated RR time reference.
    iRR : array
        Interpolated instantaneous RR intervals.
    iHR : array
        Interpolated instantaneous heart rate.
    VLF : float
        Very low frequency band power [0.003, 0.04) Hz.
    LF : float
        Low frquency band power [0.04, 0.15) Hz.
    HF : float
        High frequency band power [0.15, 0.4) Hz.
    TF : float
        Total power in the VLF, LF, and HF bands.
    L2HF : float
        Ratio of LF to HF power.
    nuLF : float
        LF power in normalized units.
    nuHF : float
        HF power in normalized units.
    
    """
    
    # resample
    its, iRR = rr_resample(ts, RR, sampling_rate=sampling_rate)
    iHR = 60. / iRR
    
    size = int(5 * sampling_rate)
    f, pwr = ss.welch(iRR, sampling_rate, window='hann', nperseg=size,
                      noverlap=size/2, nfft=1024, scaling='density')
    
    # VLF
    idx = np.logical_and(0.003 <= f, f < 0.04)
    x = f[idx]
    y = pwr[idx]
    VLF = metrics.auc(x, y)
    
    # LF
    idx = np.logical_and(0.04 <= f, f < 0.15)
    x = f[idx]
    y = pwr[idx]
    LF = metrics.auc(x, y)
    
    # HF
    idx = np.logical_and(0.15 <= f, f < 0.4)
    x = f[idx]
    y = pwr[idx]
    HF = metrics.auc(x, y)
    
    TF = VLF + LF + HF
    L2HF = LF / HF
    nuLF = LF / (TF - VLF)
    nuHF = HF / (TF - VLF)
    
    return its, iRR, iHR, VLF, LF, HF, TF, L2HF, nuLF, nuHF, f, pwr
Ejemplo n.º 43
0
def elevation_spectrum(eta,
                       sample_rate,
                       nnft,
                       window='hann',
                       detrend=True,
                       noverlap=None):
    """
    Calculates the wave energy spectrum from wave elevation time-series

    Parameters
    ------------
    eta: pandas DataFrame
        Wave surface elevation [m] indexed by time [datetime or s]
    sample_rate: float
        Data frequency [Hz]
    nnft: integer
        Number of bins in the Fast Fourier Transform
    window: string (optional)
        Signal window type. 'hann' is used by default given the broadband
        nature of waves. See scipy.signal.get_window for more options.
    detrend: bool (optional)
        Specifies if a linear trend is removed from the data before calculating
        the wave energy spectrum.  Data is detrended by default.
    noverlap: int, optional
        Number of points to overlap between segments. If None,
        ``noverlap = nperseg / 2``.  Defaults to None.

    Returns
    ---------
    S: pandas DataFrame
        Spectral density [m^2/Hz] indexed by frequency [Hz]
    """

    # TODO: Add confidence intervals, equal energy frequency spacing, and NDBC
    #       frequency spacing
    # TODO: may need an assert for the length of nnft- signal.welch breaks when nfft is too short
    # TODO: check for uniform sampling
    assert isinstance(eta, pd.DataFrame), 'eta must be of type pd.DataFrame'
    assert isinstance(sample_rate,
                      (float, int)), 'sample_rate must be of type int or float'
    assert isinstance(nnft, int), 'nnft must be of type int'
    assert isinstance(window, str), 'window must be of type str'
    assert isinstance(detrend, bool), 'detrend must be of type bool'
    assert nnft > 0, 'nnft must be > 0'
    assert sample_rate > 0, 'sample_rate must be > 0'

    S = pd.DataFrame()
    for col in eta.columns:
        data = eta[col]
        if detrend:
            data = _signal.detrend(data.dropna(), axis=-1, type='linear', bp=0)
        [f, wave_spec_measured] = _signal.welch(data,
                                                fs=sample_rate,
                                                window=window,
                                                nperseg=nnft,
                                                nfft=nnft,
                                                noverlap=noverlap)
        S[col] = wave_spec_measured
    S.index = f
    S.columns = eta.columns

    return S
Ejemplo n.º 44
0
         linestyle='--',
         color="#3498db")

plt.xlim([0, 69])
plt.ylim([0, 1.01])
plt.show()
plt.savefig('1usa-germany.svg')

dates, infections_perday, deaths_perday = compute_ma()

s1 = infections_perday[offset + 40:]
s2 = deaths_perday[offset + 40:]

f, p1 = welch(s1,
              nperseg=20,
              noverlap=19,
              detrend='linear',
              nfft=256,
              scaling='density')
f, p2 = welch(s2,
              nperseg=20,
              noverlap=19,
              detrend='linear',
              nfft=256,
              scaling='density')
plt.figure()
plt.plot(1 / f, p1 / p1.max(), linewidth=2)
plt.xlim([2, 20])
plt.plot(1 / f, p2 / p2.max(), linewidth=2)
plt.xlim([2, 20])

dates, infections_perday, deaths_perday = compute_ma('germany')
Ejemplo n.º 45
0
def process(
        auscultation_signal,
        sr,
        start=0,  # time
        end=0,  # time
        original_spectrum=0,
        original_time_freq=0,
        bandpass_filter=1,
        bandpass_graph=0,
        bandpass_spectrum=0,
        bandpass_time_freq=0,
        export_bandpass=0,  # .mat (1), .wav (2)
        wavelet=1,
        x_min=0,
        x_max=0,
        level=4,
        thershold='Minimax',  # Universal, Minimax
        ponder='Multi nivel',  # Comun, Primer nivel, Multi nivel
        hardness='Suave',  # Duro, Suave
        see='Comparar',  # Ver filtrada, Ver original, Comparar, Aprox y detalles, Multi nivel, Detalles filtrados, Multi nivel
        wavelet_graph=0,
        wavelet_spectrum=0,
        wavelet_time_freq=0,
        export_wavelet=0,  # .mat (1), .wav (2)
        compare=0):

    if end == 0: end = len(auscultation_signal)

    if (x_max == 0): x_max = len(auscultation_signal)
    elif (x_max < x_min):
        x_min = 0
        x_max = len(auscultation_signal)
    elif (x_max > len(auscultation_signal)):
        x_max = len(auscultation_signal)

    time = np.arange(0, len(auscultation_signal) / sr, 1 / sr)

    # Original Signal

    # Show spectrum of the signal
    if original_spectrum == 1:
        plt.figure()
        f, Pxx = signal.welch(
            auscultation_signal[(time >= start) & (time <= end)], sr,
            'hanning', sr * 2, sr)
        plt.title('Original Signal Spectrum')
        plt.plot(f, Pxx)
        plt.xlabel('Frequency')
        plt.ylabel('Pxx')

    # Show time freq analysis
    if original_time_freq == 1:
        n_mels = 128
        hop_length = 256  # 2^8 = 256
        n_fft = 1024  # 2^10 = 1024
        plt.figure()

        S = librosa.feature.melspectrogram(
            auscultation_signal[(time >= start) & (time <= end)],
            sr=sr,
            n_fft=n_fft,
            hop_length=hop_length,
            n_mels=n_mels)

        S_DB = librosa.power_to_db(S, ref=np.max)
        librosa.display.specshow(S_DB,
                                 sr=sr,
                                 hop_length=hop_length,
                                 x_axis='time',
                                 y_axis='mel')

        plt.colorbar(format='%+2.0f dB')
        plt.title('Original Signal Time-Frequency')

# BandPass

# Filter the signal with a bandpass with cutoff[100:1000]
# (Fs, LowCutOff, HighcutOff, RevFilt, Signal, Graph response)
    if bandpass_filter == 1:
        if bandpass_graph != 1: bandpass_graph = 0
        filter_generated = generate_filter(sr,
                                           100,
                                           1000,
                                           0,
                                           auscultation_signal,
                                           graph=bandpass_graph)
        bandpass_signal = apply_filter(filter_generated, auscultation_signal)
        bandpass_signal = np.asfortranarray(bandpass_signal)

    # Show spectrum of the signal after BandPass
    if bandpass_spectrum == 1:
        plt.figure()
        f, Pxx = signal.welch(bandpass_signal[(time >= start) & (time <= end)],
                              sr, 'hanning', sr * 2, sr)
        plt.title('After BandPass Signal Spectrum')
        plt.plot(f, Pxx)
        plt.xlabel('Frequency')
        plt.ylabel('Pxx')

    # Show time freq analysis after BandPass filter
    if bandpass_time_freq == 1:
        n_mels = 128
        hop_length = 256  # 2^8 = 256
        n_fft = 1024  # 2^10 = 1024
        plt.figure()

        S = librosa.feature.melspectrogram(bandpass_signal[(time >= start)
                                                           & (time <= end)],
                                           sr=sr,
                                           n_fft=n_fft,
                                           hop_length=hop_length,
                                           n_mels=n_mels)

        S_DB = librosa.power_to_db(S, ref=np.max)
        librosa.display.specshow(S_DB,
                                 sr=sr,
                                 hop_length=hop_length,
                                 x_axis='time',
                                 y_axis='mel')

        plt.colorbar(format='%+2.0f dB')
        plt.title('After BandPass Signal Time-Frequency')

    # Export Wavelet to: .mat (1) or .wav (2)
    if export_bandpass == 1:
        sio.savemat(
            'filtered_by_bandpass.mat',
            {'filtered': bandpass_signal[(time >= start) & (time <= end)]})

    elif export_bandpass == 2:
        sio.savemat('filtered_by_bandpass.mat', {'filtered': bandpass_signal})

# Wavelet

# Apply Wavelet Filter
    if wavelet == 1:
        x_min = x_min
        x_max = x_max
        graph = wavelet_graph
        level = level
        thershold = thershold  # Universal, Minimax
        ponder = ponder  # Comun, Primer nivel, Multi nivel
        hardness = hardness  # Duro, Suave
        see = see  # Ver filtrada, Ver original, Comparar, Aprox y detalles, Multi nivel, Detalles filtrados, Multi nivel
        signal_after_wavelet = procesador.wavelet(bandpass_signal, x_min,
                                                  x_max, graph, level,
                                                  thershold, ponder, hardness,
                                                  see)
# 2nd BandPass
    filtered_signal = apply_filter(filter_generated, signal_after_wavelet)
    filtered_signal = np.asfortranarray(filtered_signal)

    # Show spectrum of the signal after wavelet filter
    if wavelet_spectrum == 1:
        plt.figure()
        f, Pxx = signal.welch(filtered_signal[(time >= start) & (time <= end)],
                              sr, 'hanning', sr * 2, sr)
        plt.title('After Wavelet Spectrum')
        plt.plot(f, Pxx)
        plt.xlabel('Frequency')
        plt.ylabel('Pxx')

    # Show time freq analysis after wavelet filter
    if wavelet_time_freq == 1:
        n_mels = 128
        hop_length = 256  # 2^9
        n_fft = 1024  # 2^11
        plt.figure()

        S = librosa.feature.melspectrogram(filtered_signal[(time >= start)
                                                           & (time <= end)],
                                           sr=sr,
                                           n_fft=n_fft,
                                           hop_length=hop_length,
                                           n_mels=n_mels)

        S_DB = librosa.power_to_db(S, ref=np.max)
        librosa.display.specshow(S_DB,
                                 sr=sr,
                                 hop_length=hop_length,
                                 x_axis='time',
                                 y_axis='mel')

        plt.colorbar(format='%+2.0f dB')
        plt.title('After Wavelet Time-Frequency')

    # Export Wavelet to: .mat (1) or .wav (2)
    if export_wavelet == 1:
        sio.savemat(
            'filtered_by_wavelet.mat',
            {'filtered': filtered_signal[(time >= start) & (time <= end)]})

    elif export_wavelet == 2:
        librosa.output.write_wav(
            'nivel_' + str(level) + '_' + str(thershold) + '_' + str(ponder) +
            '_' + str(hardness) + '.wav',
            10 * filtered_signal[(time >= start) & (time <= end)], sr)

    # Compare Signals
    if compare == 1:
        plt.figure()
        plt.subplot(3, 1, 1)
        plt.title('Original')
        librosa.display.waveplot(auscultation_signal[(time >= start)
                                                     & (time <= end)],
                                 sr=sr)
        plt.grid()
        plt.subplot(3, 1, 2)
        plt.title('BandPass')
        librosa.display.waveplot(bandpass_signal[(time >= start)
                                                 & (time <= end)],
                                 sr=sr)
        plt.grid()
        plt.subplot(3, 1, 3)
        plt.title('BandPass + Wavelet + BandPass')
        librosa.display.waveplot(filtered_signal[(time >= start)
                                                 & (time <= end)],
                                 sr=sr)
        plt.grid()

        plt.tight_layout()

    return time, filtered_signal[(time >= start) & (time <= end)]
Ejemplo n.º 46
0
import numpy as np
ut = utility.Utility_Functions()
import matplotlib.pyplot as plt
# print("s" , ut.condLFP_data.shape)
# print("s" , ut.LFP_data.shape)

for i in range(1, 9):
    trials1 = ut.LFP_data[ut.condLFP_data[:, 0] == i]
    trials2 = ut.LFP_data[ut.condLFP_data[:, 0] == i + 8]
    # print(trials1.shape)
    # trials2 = ut.LFP_data[:, (ut.condLFP_data == i+8).squeeze()]
    print(trials1.shape)
    print(trials2.shape)
    trials = list(trials1) + list(trials2)
    trials = np.array(trials)
    freqs, psd = signal.welch(trials[0, 2700:3200])

    # plt.figure(figsize=(5, 4)  )
    plt.subplot(2, 4, i)
    plt.semilogx(freqs, psd)
    plt.title('PSD: power spectral density for angel ' + str(i) +
              "\n in time [2700,3200]")
    plt.xlabel('Frequency')
    plt.ylabel('Power')
    plt.tight_layout()
plt.subplots_adjust(left=0.02, wspace=0.5, bottom=0.06, hspace=0.5)
plt.show()

np.random.seed(0)

time_step = .01
Ejemplo n.º 47
0
def power_spectral_density(data: np.ndarray,
                           band: Tuple[float, float],
                           sampling_rate: float = 100.0,
                           window_length: float = 4.0,
                           plot: bool = False,
                           method: PSD_TYPE = PSD_TYPE.WELCH,
                           relative=False):
    """Power spectral density:

    Many thanks to: https://raphaelvallat.github.io/bandpower.html

    Parameters
    ----------
        data: Numpy Array.
            Time series data in the form of a numpy ndarray used to estimate the
                power spectral density.
        band: tuple.
            frequency band psd to export. Note this must be within the Nyquist frequency
            for your data. Approximated as sampling rate / 2.
        sampling_rate: float
            Sampling rate of the data in # of samples per second.
        window_length: float
            Length in seconds of data window.
        plot: boolean.
            Whether of not to plot the PSD estimated. Helpful for debugging and exploration.
        method: PSD_TYPE
            Type of PSD estimation method to use during calculation.
        relative: boolean
            Whether or not to express the power in a frequency band as a percentage of the
            total power of the signal.

    """
    band = np.asarray(band)
    low, high = band

    # Compute the modified periodogram (Welch)
    if method == PSD_TYPE.WELCH:
        nperseg = window_length * sampling_rate
        freqs, psd = welch(data, sampling_rate, nperseg=nperseg)

    # Compute the modified periodogram (MultiTaper)
    elif method == PSD_TYPE.MULTITAPER:
        psd, freqs = psd_array_multitaper(data,
                                          sampling_rate,
                                          adaptive=True,
                                          normalization='full',
                                          verbose=False)

    # Find index of band in frequency vector
    idx_band = np.logical_and(freqs >= low, freqs <= high)

    # Frequency resolution
    freq_res = freqs[1] - freqs[0]

    # Integral approximation of the spectrum using parabola (Simpson's rule)
    bp = simps(psd[idx_band], dx=freq_res)

    # Plot the power spectrum
    if plot:
        sns.set(font_scale=1.2, style='white')
        plt.figure(figsize=(8, 4))
        plt.plot(freqs, psd, color='k', lw=2)
        plt.xlabel('Frequency (Hz)')
        plt.ylabel('Power spectral density (V^2 / Hz)')
        plt.ylim([0, psd.max() * 1.1])
        plt.title(f'{method.value}')
        plt.xlim([0, sampling_rate / 2])
        sns.despine()
        plt.show()

    # Whether or not to return PSD as a percentage of total power
    if relative:
        bp /= simps(psd, dx=freq_res)

    return bp
Ejemplo n.º 48
0
def analyze_line_delay(filename, diagnostic_plots=False):
    '''
    Analyze the file delay from a tagged file.

    :param filename: the name of the file containing the delay data.
    :param diagnostic_plots: saves two diagnostic plots in png.
    :return: the delay in seconds.
    '''

    print_debug("Analyzing line delay info form file: \'%s\' ..." % (filename))

    decimation = 2
    zz = signal.decimate(openH5file(filename)[0], decimation, ftype="fir")
    info = get_rx_info(filename, ant=None)
    decimation *= info['decim']
    freq, Pxx = signal.welch(zz.real,
                             nperseg=len(zz),
                             fs=int(info['rate'] / float(decimation)),
                             detrend='linear',
                             scaling='density')

    if diagnostic_plots:
        diag_fig = pl.figure()
        pl.plot(zz.real, label="real")
        pl.plot(zz.imag, label="imag")
        pl.plot(np.abs(zz), label="abs")
        pl.title("Delay acquisition diagnostic.\n total decimation: %d" %
                 decimation)
        pl.xlabel("Samples")
        pl.ylabel("ADCu")
        pl.legend()
        pl.grid()
        pl.savefig("Delay_diagnostic.png")
        pl.close(diag_fig)

        diag_fig = pl.figure()
        pl.plot(np.angle(zz), label="angle")
        pl.title("Delay acquisition diagnostic.\n total decimation: %d" %
                 decimation)
        pl.xlabel("Samples")
        pl.ylabel("ADCu")
        pl.legend()
        pl.grid()
        pl.savefig("Delay_diagnostic_phase.png")
        pl.close(diag_fig)

        diag_fig = pl.figure()
        pl.title("Delay acquisition diagnostic.")
        Pxx = 20 * np.log10(Pxx)
        pl.xlabel("Frequency [Hz]")
        pl.ylabel("ADC dB")
        pl.semilogx(freq, Pxx, label="real")
        pl.legend()
        pl.grid()
        pl.savefig("Delay_diagnostic_FFT.png")
        pl.close(diag_fig)

    coeff = float(info['chirp_t'][0]) / float(
        np.abs(info['freq'][0] - info['chirp_f'][0]))

    print_debug("Coefficient is: " + str(coeff))

    print_debug("Max low freq found: " + str(freq[Pxx.argmax()]))

    delay = freq[Pxx.argmax()] * coeff

    delay = int(delay * 2e8) / 2.e8

    print_debug("Delay found %d ns" % int(delay * 1e9))

    return delay
Ejemplo n.º 49
0
def puv_quick(pressure,
              u,
              v,
              depth,
              height_of_pressure,
              height_of_velocity,
              sampling_frequency,
              fft_length=512,
              rho=1025.,
              first_frequency_cutoff=1 / 50,
              infra_gravity_cutoff=0.05,
              last_frequency_cutoff=1 / 5,
              fft_window_type='hanning',
              show_diagnostic_plot=False,
              check_variances=False,
              variance_error=0.0,
              overlap_length='default'):
    """
    Determine wave heights from pressure, east_velocity, v velocity data

    Parameters
    ----------
    pressure : array_like
        pressure (dbar)
    u :  array_like
        u velocities (m/s)
    v :  array_like
        v velocities (m/s)
    depth : float
        Average water depth (m, positive number)
    height_of_pressure : float
        Height of pressure sensor off bottom (m, positive number)
    height_of_velocity : float
        Height of velocity sensor off bottom (m, positive number)
    sampling_frequency : float
        Hz
    fft_length : int
        Length of data to window and process
    rho : float
        Water density (kg/m^3)
    fft_window_type : str
        Data fft_window for spectral calculation, per scipy signal package
    first_frequency_cutoff : float
        Low-frequency cutoff for wave motions
    infra_gravity_cutoff : float
        Infra-gravity wave frequency cutoff
    last_frequency_cutoff : float
        High-frequency cutoff for wave motions
    show_diagnostic_plot : bool
        print plots and other checks
    check_variances : bool
        test to see if variance is preserved in calculations
    variance_error : float
        tolerance for variance preservation, in percent
    overlap_length : str "default" or int length, default will result in fft_length / 2

    Returns
    -------
    dict::
        'Hrmsp': Hrms (=Hmo) from pressure
        'Hrmsu': Hrms from u,v
        'ubr': Representative orbital velocity amplitude in freq. band
            ( first_frequency_cutoff <= f <= last_frequency_cutoff ) (m/s)
        'omegar': Representative orbital velocity (radian frequency)
        'Tr': Representative orbital velocity period (s)
        'Tpp': Peak period from pressure (s)
        'Tpu': Peak period from velocity (s)
        'phir': Representative orbital velocity direction (angles from x-axis, positive ccw)
        'azr': Representative orb. velocity direction (deg; geographic azimuth; ambiguous =/- 180 degrees)
        'ublo': ubr in freq. band (f <= first_frequency_cutoff) (m/s)
        'ubhi': ubr in freq. band (f >= last_frequency_cutoff) (m/s)
        'ubig': ubr in infra-gravity freq. band (first_frequency_cutoff f <= 1/20) (m/s)
        'figure': figure handle
        'axis': axis handle
        'variance_test_passed': True if passing

    References
    ----------
    Madsen (1994) Coastal Engineering 1994, Proc., 24th, Intl. Conf., Coastal Eng. Res. Council / ASCE. pp.384-398.
        (esp. p. 395)
    Thorton & Guza

    Acknowledgements
    ----------------
    converted to python and updated by Marinna Martini from Chris Sherwood's puvq.m.
    puvq.m also had contributions from Laura Landerman and Patrick Dickudt
    """

    gravity = 9.81  # m/s^2
    if fft_window_type is 'hanning':
        fft_window_type = 'hann'  # this is just the way scipy signal likes it
    if overlap_length is "default":
        overlap_length = int(np.floor(fft_length / 2))

    pressure = spsig.detrend(pressure)
    u = spsig.detrend(u)
    v = spsig.detrend(v)

    # compute wave height from velocities

    # Determine velocity spectra for u and v
    [frequencies, Gpp] = spsig.welch(rho * gravity * pressure,
                                     fs=sampling_frequency,
                                     window=fft_window_type,
                                     nperseg=fft_length,
                                     noverlap=overlap_length)

    df = frequencies[2] - frequencies[1]
    [_, Guu] = spsig.welch(u,
                           fs=sampling_frequency,
                           window=fft_window_type,
                           nperseg=fft_length,
                           noverlap=overlap_length)
    [_, Gvv] = spsig.welch(v,
                           fs=sampling_frequency,
                           window=fft_window_type,
                           nperseg=fft_length,
                           noverlap=overlap_length)

    # determine wave number
    omega = np.array([2 * np.pi * x for x in frequencies
                      ])  # omega must be numpy array for qkfs
    # catch numpy errors
    np.seterr(divide='ignore', invalid='ignore')
    k = qkfs(omega, float(depth))  # make sure it is float, or qkfs will bomb
    np.seterr(divide=None, invalid=None)

    # compute linear wave transfer function
    kh = k * depth
    kzp = k * height_of_pressure
    kzuv = k * height_of_velocity
    nf = len(omega)
    Hp = np.ones(nf)
    Huv = np.ones(nf)

    # change wavenumber at 0 Hz to 1 to avoid divide by zero
    i = np.array(
        range(nf)
    )  # this is an index, thus needs to start at first element, in this case 0
    # for some reason in the MATLAB version CRS tests omega for nans instead of k.
    # Here we test k also because that's where the nans show up
    if np.isnan(omega[0]) or np.isnan(
            k[0]) or (omega[0] <= 0):  # 0 Hz is the first element
        i = i[1:]
        Hp[0] = 1
        Huv[0] = 1

    Hp[i] = rho * gravity * (np.cosh(kzp[i]) / np.cosh(kh[i]))
    Huv[i] = omega[i] * (np.cosh(kzuv[i]) / np.sinh(kh[i]))

    # combine horizontal velocity spectra
    Guv = Guu + Gvv

    # create cut off frequency, so noise is not magnified
    # at least in first testing, subtracting 1 here got closer to the intended freq. cutoff value
    ff = np.argmax(frequencies > first_frequency_cutoff) - 1
    lf = np.argmax(frequencies > last_frequency_cutoff)

    # Determine wave height for velocity spectra
    Snp = Gpp[ff:lf] / (Hp[ff:lf]**2)
    Snu = Guv[ff:lf] / (Huv[ff:lf]**2)
    fclip = frequencies[ff:lf]

    # Determine rms wave height (multiply by another sqrt(2) for Hs)
    # Thornton and Guza say Hrms = sqrt(8 mo)
    Hrmsu = 2 * np.sqrt(2 * np.sum(Snu * df))
    Hrmsp = 2 * np.sqrt(2 * np.sum(Snp * df))

    # These are representative orbital velocities for w-c calculations,
    # according to Madsen (1994) Coastal Engineering 1994, Proc., 24th
    # Intl. Conf., Coastal Eng. Res. Council / ASCE. pp.384-398.
    # (esp. p. 395)
    ubr = np.sqrt(2 * np.sum(Guv[ff:lf] * df))
    ubr_check = np.sqrt(2 * np.var(u) + 2 * np.var(v))
    omegar = np.sum(omega[ff:lf] * Guv[ff:lf] * df) / np.sum(Guv[ff:lf] * df)
    Tr = 2 * np.pi / omegar

    if len(np.where(np.isnan(Snp))) > 0 | len(np.where(Snp == 0)) > 0:
        Tpp = np.nan
    else:
        jpeak = np.argmax(Snp)  # index location of the maximum value
        Tpp = 1 / fclip[jpeak]

    if len(np.where(np.isnan(Snu))) > 0 | len(np.where(Snu == 0)) > 0:
        Tpu = np.nan
    else:
        jpeak = np.argmax(Snu)
        Tpu = 1 / fclip[jpeak]

    # phi is angle wrt to x axis; this assumes Guu is in x direction
    # phir = atan2( sum(Guu(ff:lf)*df), sum(Gvv(ff:lf)*df) );

    # this is the line changed on 6/24/03 - I still think it is wrong (CRS)
    # phir = atan2( sum(Gvv(ff:lf)*df), sum(Guu(ff:lf)*df) );

    # This is Jessie's replacement for direction
    # 12/08 Jessie notes that Madsen uses velocity and suggests
    # Suu = sqrt(Guu);
    # Svv = sqrt(Gvv);
    # Suv = sqrt(Guv);
    # but I (CRS) think eqn. 24 is based on u^2, so following is ok:
    rr = np.corrcoef(u, v)
    ortest = np.sign(rr[1][0])
    phir = np.arctan2(ortest * np.sum(Gvv[ff:lf] * df),
                      np.sum(Guu[ff:lf] * df))

    # convert to degrees; convert to geographic azimuth (0-360, 0=north)
    azr = 90 - (180 / np.pi) * phir

    # Freq. bands for variance contributions
    ig = np.max(np.where(frequencies <= infra_gravity_cutoff))
    # low freq, infragravity, high-freq
    if 1 < ff:
        ublo = np.sqrt(2 * np.sum(Guv[1:ff] * df))
    else:
        ublo = 0
    if ig > ff:
        ubig = np.sqrt(2 * np.sum(Guv[ff:ig] * df))
    else:
        ubig = 0
    if lf < fft_length:
        ubhi = np.sqrt(2 * np.sum(Guv[lf:] * df))
    else:
        ubhi = 0

    ws = {
        'Hrmsp': Hrmsp,
        'Hrmsu': Hrmsu,
        'ubr': ubr,
        'ubr_check': ubr_check,
        'omegar': omegar,
        'Tr': Tr,
        'Tpp': Tpp,
        'Tpu': Tpu,
        'phir': phir,
        'azr': azr,
        'ublo': ublo,
        'ubhi': ubhi,
        'ubig': ubig,
    }

    if check_variances:
        variance_preserved = test_variances(u,
                                            v,
                                            pressure,
                                            Gpp,
                                            Guu,
                                            Gvv,
                                            df,
                                            allowable_error=variance_error)
        ws['variance_test_passed'] = variance_preserved

    if show_diagnostic_plot:
        fig, ax = plot_spectra(Guu, Gvv, Guv, Gpp, frequencies,
                               first_frequency_cutoff, ff,
                               last_frequency_cutoff, lf, infra_gravity_cutoff,
                               ig)
        ws['figure'] = fig
        ws['axis'] = ax

    return ws
Ejemplo n.º 50
0
fig, axes = plt.subplots(2, 2, figsize=(8, 4))

# Plot the timeseries
ax = axes[0][0]
ax.plot(times, 1e9 * signal1, lw=0.5)
ax.set(xlabel='Time (s)',
       xlim=times[[0, -1]],
       ylabel='Amplitude (Am)',
       title='Signal 1')
ax = axes[0][1]
ax.plot(times, 1e9 * signal2, lw=0.5)
ax.set(xlabel='Time (s)', xlim=times[[0, -1]], title='Signal 2')

# Power spectrum of the first timeseries
f, p = welch(signal1, fs=sfreq, nperseg=128, nfft=256)
ax = axes[1][0]
# Only plot the first 100 frequencies
ax.plot(f[:100], 20 * np.log10(p[:100]), lw=1.)
ax.set(xlabel='Frequency (Hz)',
       xlim=f[[0, 99]],
       ylabel='Power (dB)',
       title='Power spectrum of signal 1')

# Compute the coherence between the two timeseries
f, coh = coherence(signal1, signal2, fs=sfreq, nperseg=100, noverlap=64)
ax = axes[1][1]
ax.plot(f[:50], coh[:50], lw=1.)
ax.set(xlabel='Frequency (Hz)',
       xlim=f[[0, 49]],
       ylabel='Coherence',
Ejemplo n.º 51
0
def timeseriesPUV(p, u, v, t, waterDepth, gaugeDepth):
    """The goal with this function is to create time series anaylysis work flow
         runs welch method fft with 512 record segments, with 1/4 overlab and 5 freq bin band averaging
    
    corrects pressure spectra to surface spectra using pressure response function
    
     below parameters and makes them into magical wave data

    Args:
      p: pressure in cm
      u: u velocities
      v: v velocities
      t: time stamp
      waterDepth: positive in meters
      gaugeDepth: negative in meters
      frequency: spectra
      a1: interped to np.arange(0.04, 0.5, 0.0075)
      b1: interped to np.arange(0.04, 0.5, 0.0075)
      a2: interped to np.arange(0.04, 0.5, 0.0075)
      b2: interped to np.arange(0.04, 0.5, 0.0075)

    Returns:
      param frequency spectra

    """
    from scipy.signal import welch, csd

    Fsamp = 1 / np.median(np.diff(t))  # sample frequency (not period)
    nseg = 512  # 512
    overlap = nseg / 4
    bave = 5  # number of spectral bands to average (taken from kent)

    # Calculate spectra in each componant
    # x is north, y is east in kents code (used for  a's b's)
    pDemeaned = (p - np.mean(p)) / 100  # demean pressure and convert to meters
    [f1, Sp] = welch(x=pDemeaned, window='hanning', fs=Fsamp, nperseg=nseg, noverlap=overlap, nfft=None,
                     return_onesided=True, detrend='linear')
    [f1, Su] = welch(x=u, window='hanning', fs=Fsamp, nperseg=nseg, noverlap=overlap, nfft=None, return_onesided=True,
                     detrend='linear')
    [f1, Sv] = welch(x=v, window='hanning', fs=Fsamp, nperseg=nseg, noverlap=overlap, nfft=None, return_onesided=True,
                     detrend='linear')
    # create cross spectral power across the 3
    [f1, CrossPU] = csd(y=pDemeaned, x=u, fs=Fsamp, nperseg=nseg, noverlap=overlap, return_onesided=True,
                        window='hann')
    [f1, CrossPV] = csd(y=pDemeaned, x=v, fs=Fsamp, nperseg=nseg, noverlap=overlap, return_onesided=True,
                        window='hann')
    [f1, CrossUV] = csd(y=v, x=u, fs=Fsamp, nperseg=nseg, noverlap=overlap, return_onesided=True,
                        window='hann')
    ## now Do some frequency band Averaging
    # first remove first index of array  "remove DC compoonents"
    f1 = f1[1:]
    Sp = np.real(Sp[1:])
    Su = np.real(Su[1:])
    Sv = np.real(Sv[1:])
    CrossPU = CrossPU[1:]
    CrossPV = CrossPV[1:]
    CrossUV = CrossUV[1:]
    # correcting Pressure spectra to surface spectra
    L, _, _ = dispersion(waterDepth, T=1 / f1)
    prF = prFunc(L, waterDepth, gaugeDepth)  #
    Sp = Sp / prF ** 2  # getting surface corrected energy spectrum

    #  Beginning to Setup For Band Averaging
    dk = int(np.floor(bave / 2))

    ki = 0
    freq, SpAve, SuAve, SvAve, CrossPUave, CrossPVave, CrossUVave = [], [], [], [], [], [], []
    for kk in range(dk + 1, len(Sp) - dk, bave):
        avgIdxs = np.linspace(kk - dk, kk + dk, num=int((kk + dk) - (kk - dk) + 1), endpoint=True, dtype=int)
        freq = np.append(freq, f1[int(kk)])  # taking the first frequency for the bin label
        # bin averaging frequency spectra across bave frequency bins
        SpAve.append(np.sum(Sp[avgIdxs]) / bave)
        SuAve.append(np.sum(Su[avgIdxs]) / bave)
        SvAve.append(np.sum(Sv[avgIdxs]) / bave)
        # bin averaging cross correlations
        CrossPUave.append(np.sum(CrossPU[avgIdxs]) / bave)  # Press - FRF X
        CrossPVave.append(np.sum(CrossPV[avgIdxs]) / bave)  # Press - FRF Y
        CrossUVave.append(np.sum(CrossUV[avgIdxs]) / bave)  # FRF X - FRF Y
    # convert back to Numpy array
    freq = np.array(freq)
    SpAve = np.array(SpAve)
    SuAve = np.array(SuAve)
    SvAve = np.array(SvAve)
    CrossPUave = np.array(CrossPUave)
    CrossPVave = np.array(CrossPVave)
    CrossUVave = np.array(CrossUVave)

    # Extracting as and bs
    a1 = np.imag(CrossPUave) / np.sqrt(SpAve * (SuAve + SvAve))
    b1 = -np.imag(CrossPVave) / np.sqrt(SpAve * (SuAve + SvAve))
    a2 = (SuAve - SvAve) / (SvAve + SuAve)
    b2 = -2 * np.real(CrossUVave) / (SvAve + SuAve)

    wfreq = np.arange(0.04, 0.5, 0.0075)  # frequencies to interp to
    wDeg = np.arange(0, 360, 5)
    # interpolating to reasonable frequency banding
    import scipy.interpolate as interp
    f = interp.interp1d(freq, a1, kind='linear')
    a1interp = f(wfreq)
    f = interp.interp1d(freq, a2, kind='linear')
    a2interp = f(wfreq)
    f = interp.interp1d(freq, b1, kind='linear')
    b1interp = f(wfreq)
    f = interp.interp1d(freq, b2, kind='linear')
    b2interp = f(wfreq)
    f = interp.interp1d(freq, SpAve, kind='linear')
    fspec = f(wfreq)

    # mlmSpec = mlm(freqs=freq, dirs=np.arange(0,360,5), c11=SpAve, c22=SuAve, c33=SvAve, c23=np.real(CrossUVave), q12=np.imag(CrossPUave), q13=np.imag(CrossPVave))

    return fspec, a1interp, b1interp, a2interp, b2interp
Ejemplo n.º 52
0
        vvec = numpy.array(v_vec)
        tvec = numpy.array(t_vec)
        numpy.save(
            'Output/' + cellname + modelname + '_NumberOfSyns_' + str(synnum) +
            '_Frequency_' + str(rate) + '_Voltage.npy', vvec)
        numpy.save(
            'Output/' + cellname + modelname + '_NumberOfSyns_' + str(synnum) +
            '_Frequency_' + str(rate) + '_Time.npy', tvec)
        apctimes = numpy.array(h.apctimes)
        spikebinvec = numpy.zeros(len(tvec))
        for x in apctimes:
            spikebinvec[numpy.where(tvec == x)] = 1

        dt = h.dt
        f, Pxx_den = signal.welch(spikebinvec, 1 / (dt / 1000), nperseg=25000)
        if synnum == 0:
            Pxx_den0 = Pxx_den
            f0 = f
        Areas[rcount][scount] = numpy.trapz(Pxx_den[(f > 4) & (f < 12)],
                                            x=f[(f > 4) & (f < 12)])
        Power[rcount][scount] = numpy.max(Pxx_den[(f > rate - 1)
                                                  & (f < rate + 1)])
        # Power[rcount][scount] = numpy.max(Pxx_den[f==rate])
        if synnum != 0:
            Pxx_den_Subtracted = Pxx_den - Pxx_den0
            AreasSubtracted[rcount][scount] = numpy.trapz(
                Pxx_den[(f > 4) & (f < 12)],
                x=f[(f > 4) & (f < 12)]) - numpy.trapz(
                    Pxx_den0[(f0 > 4) & (f0 < 12)], x=f0[(f0 > 4) & (f0 < 12)])
            PowerSubtracted[rcount][scount] = numpy.max(
Ejemplo n.º 53
0
    def test_welch_psd_behavior(self):
        # generate data by adding white noise and a sinusoid
        data_length = 5000
        sampling_period = 0.001
        signal_freq = 100.0
        noise = np.random.normal(size=data_length)
        signal = [
            np.sin(2 * np.pi * signal_freq * t)
            for t in np.arange(0, data_length *
                               sampling_period, sampling_period)
        ]
        data = n.AnalogSignal(np.array(signal + noise),
                              sampling_period=sampling_period * pq.s,
                              units='mV')

        # consistency between different ways of specifying segment length
        freqs1, psd1 = elephant.spectral.welch_psd(data,
                                                   len_segment=data_length //
                                                   5,
                                                   overlap=0)
        freqs2, psd2 = elephant.spectral.welch_psd(data,
                                                   n_segments=5,
                                                   overlap=0)
        self.assertTrue((psd1 == psd2).all() and (freqs1 == freqs2).all())

        # frequency resolution and consistency with data
        freq_res = 1.0 * pq.Hz
        freqs, psd = elephant.spectral.welch_psd(data,
                                                 frequency_resolution=freq_res)
        self.assertAlmostEqual(freq_res, freqs[1] - freqs[0])
        self.assertEqual(freqs[psd.argmax()], signal_freq)
        freqs_np, psd_np = elephant.spectral.welch_psd(
            data.magnitude.flatten(),
            fs=1 / sampling_period,
            frequency_resolution=freq_res)
        self.assertTrue((freqs == freqs_np).all() and (psd == psd_np).all())

        # check of scipy.signal.welch() parameters
        params = {
            'window': 'hamming',
            'nfft': 1024,
            'detrend': 'linear',
            'return_onesided': False,
            'scaling': 'spectrum'
        }
        for key, val in params.items():
            freqs, psd = elephant.spectral.welch_psd(data,
                                                     len_segment=1000,
                                                     overlap=0,
                                                     **{key: val})
            freqs_spsig, psd_spsig = spsig.welch(np.rollaxis(
                data, 0, len(data.shape)),
                                                 fs=1 / sampling_period,
                                                 nperseg=1000,
                                                 noverlap=0,
                                                 **{key: val})
            self.assertTrue((freqs == freqs_spsig).all()
                            and (psd == psd_spsig).all())

        # - generate multidimensional data for check of parameter `axis`
        num_channel = 4
        data_length = 5000
        data_multidim = np.random.normal(size=(num_channel, data_length))
        freqs, psd = elephant.spectral.welch_psd(data_multidim)
        freqs_T, psd_T = elephant.spectral.welch_psd(data_multidim.T, axis=0)
        self.assertTrue(np.all(freqs == freqs_T))
        self.assertTrue(np.all(psd == psd_T.T))
Ejemplo n.º 54
0
        for j, ch in enumerate(ch_plot):
            leg = []
            fb_counter = 0
            for jj, key in enumerate(keys):
                x = raw[key]
                style = '--' if fb_counter > 0 else ''
                w = 2
                if 'FB' in key:
                    fb_counter += 1
                    style = ''
                    w = fb_counter
                y = x[:, channels.index(ch)] if ch != 'ICA' else np.dot(
                    x, spatial)
                f, Pxx = welch(
                    y,
                    fs,
                    nperseg=2048,
                )
                axes[j].plot(f,
                             Pxx,
                             style,
                             c=cm(key),
                             linewidth=w,
                             alpha=0.8 if 'FB' in key else 1)
                x_plot = np.abs(hilbert(fft_filter(y, fs, band=mu_band)))
                threshold = coef * x_median[channels.index(
                    ch)] if ch != 'ICA' else coef * x_f_median
                leg.append('{}'.format(key))

            axes[j].set_xlim(7, 15)
            axes[j].axvline(x=mu_band[0], color='k', alpha=0.5)
Ejemplo n.º 55
0
    baseline_closed = baseline.loc[12001:24001, :]

    nodis = nodis_epoch.to_data_frame().reset_index(drop=True)
    buzz = buzz_epoch.to_data_frame().reset_index(drop=True)
    neutral = neutral_epoch.to_data_frame().reset_index(drop=True)

    for electrode in parietal:
        #Choose electrodes to investigate
        data_baseline_open = baseline_open[electrode]
        data_baseline_closed = baseline_closed[electrode]
        data_nodis = nodis[electrode]
        data_buzz = buzz[electrode]
        data_neutral = neutral[electrode]

        #Compute Welch transform
        freqs_baseline_open, psd_baseline_open = signal.welch(
            data_baseline_open, Fs, nperseg=sliding_window, noverlap=n_overlap)
        freqs_baseline_closed, psd_baseline_closed = signal.welch(
            data_baseline_closed,
            Fs,
            nperseg=sliding_window,
            noverlap=n_overlap)
        freqs_nodis, psd_nodis = signal.welch(data_nodis,
                                              Fs,
                                              nperseg=sliding_window,
                                              noverlap=n_overlap)
        freqs_buzz, psd_buzz = signal.welch(data_buzz,
                                            Fs,
                                            nperseg=sliding_window,
                                            noverlap=n_overlap)
        freqs_neutral, psd_neutral = signal.welch(data_neutral,
                                                  Fs,
Ejemplo n.º 56
0
 def test_empty_input_other_axis(self):
     for shape in [(3, 0), (0, 5, 2)]:
         f, p = welch(np.empty(shape), axis=1)
         assert_array_equal(f.shape, shape)
         assert_array_equal(p.shape, shape)
        freq_aux = np.array([])
        psd_aux = np.array([])

        windows = np.array([49, 35, 10, 2, 0.5
                            ]) / dt  # the size of the windows in days/dt
        lims = [0.08, 1, 3, 10, 20]  # limit frequency for windows

        freq, psd = sg.periodogram(temp, fs=1. / dt)
        ind, = np.where(freq < lims[0])
        freq_aux = np.concatenate((freq_aux, freq[ind]))
        psd_aux = np.concatenate((psd_aux, psd[ind]))

        for i in range(0, len(lims) - 1):
            freq, psd = sg.welch(temp,
                                 fs=1. / dt,
                                 window='hanning',
                                 nperseg=windows[i],
                                 noverlap=0.15)
            ind, = np.where(((freq >= lims[i]) & (freq < lims[i + 1])))
            freq_aux = np.concatenate((freq_aux, freq[ind]))
            psd_aux = np.concatenate((psd_aux, psd[ind]))
            print(1)

        freq, psd = sg.welch(temp,
                             fs=1. / dt,
                             window='hanning',
                             nperseg=windows[-1],
                             noverlap=0.15)
        ind, = np.where(freq >= lims[-1])
        freq_aux = np.concatenate((freq_aux, freq[ind]))
        psd_aux = np.concatenate((psd_aux, psd[ind]))
Ejemplo n.º 58
0
chirpLen_s = chirpLen_s + baseline_s + end_s
times_s = np.arange(0, chirpLen_s, 1.0 / sr)
numSamples = times_s[-1] * sr

bin_window = .5  #s
bin_window_step = bin_window * sr
bin_step = .1  #s
bin_step_step = bin_step * sr
Pxx_dens = list()
freqlimit = np.max([start_Hz, stop_Hz]) * 2
t_fft = np.arange(bin_window / 2, chirpLen_s - bin_window / 2, bin_step)
for start_idx, end_idx in zip(
        np.arange(0, numSamples - bin_window_step, bin_step_step),
        np.arange(bin_window_step, numSamples, bin_step_step)):
    f, Pxx_den = signal.welch(chirp[int(start_idx):int(end_idx)],
                              sr,
                              nperseg=bin_window_step)
    Pxx_dens.append(Pxx_den[:np.argmax(f > freqlimit)])

#%

f_plot = f[:np.argmax(f > freqlimit)]
fig = plt.figure(figsize=[5, 5])
ax_chirp = fig.add_subplot(211)
ax_fft = fig.add_subplot(212)
ax_chirp.plot(times_s, chirp)
fftfig = ax_fft.imshow(np.stack(Pxx_dens).T[::-1, :], extent=[0, 3, 0, 1])
yticks = ax_fft.get_yticks()
yticks_f = f_plot[np.asarray(yticks * (len(f_plot) - 1), int)]
ax_fft.set_yticklabels(yticks_f)
xticks = ax_fft.get_xticks() / 3
Ejemplo n.º 59
0
def plotNodes(i):
    global data

    start_time = time.time()
    inlet = StreamInlet(streams[0])

    # get a new sample
    sample = inlet.pull_sample()
    newdata = np.asarray(sample[0][:n])
    # print(newdata)

    # delete first row of data
    data = np.delete(data, 0, 0)

    # add newdata as a row at the end of data. columns=electrodes rows=timestep
    data = np.vstack([data, newdata])
    data = np.transpose(data)

    # compute power spectrum of data
    f, ps = sps.welch(data, fs=26)
    print("ps", ps)

    # get the amplitudes associated with the various bands of frequencies
    extractAmplitudeDelta = getAmplitudesByFrequencyBand(ps, 0)
    extractAmplitudeTheta = getAmplitudesByFrequencyBand(ps, 1)
    extractAmplitudeAlpha = getAmplitudesByFrequencyBand(ps, 2)
    tempDelta = np.asarray(extractAmplitudeDelta)
    tempTheta = np.asarray(extractAmplitudeTheta)
    tempAlpha = np.asarray(extractAmplitudeAlpha)

    # temp holds mean of each row in extractAmplitude
    tempDelta = np.mean(tempDelta, axis=1)
    tempTheta = np.mean(tempTheta, axis=1)
    tempAlpha = np.mean(tempAlpha, axis=1)

    # square all values to make them 0 <= x <= 1
    tempDelta = np.square(tempDelta)
    tempTheta = np.square(tempTheta)
    tempAlpha = np.square(tempAlpha)

    # calculate zscores for the array
    zscoreArrayDelta = stats.zscore(tempDelta)
    zscoreArrayTheta = stats.zscore(tempTheta)
    zscoreArrayAlpha = stats.zscore(tempAlpha)
    # do relative here
    # next line creates positive and negative zscores, so if the value was between 0 to 0.5, it is
    # scaled to between -1 and 0, and if the value was between 0.5 and 1, it is scaled to between
    # 0 and 1
    zscoreArrayDelta = (
        (zscoreArrayDelta / np.amax(zscoreArrayDelta)) / 2) + 0.5
    zscoreArrayTheta = (
        (zscoreArrayTheta / np.amax(zscoreArrayTheta)) / 2) + 0.5
    zscoreArrayAlpha = (
        (zscoreArrayAlpha / np.amax(zscoreArrayAlpha)) / 2) + 0.5

    # define vectors for plot colors and opacity
    # altColors = freqs / 33
    colorsDelta = cmap(zscoreArrayDelta)
    colorsTheta = cmap(zscoreArrayTheta)
    colorsAlpha = cmap(zscoreArrayAlpha)

    # colors.astype(float)
    # colors[:, -1] = maxes / maxes.max()
    # print(altColors)
    # print(colors)

    ax1.set_xlim(-6, 6)
    ax1.set_ylim(-6, 6)
    ax2.set_xlim(-6, 6)
    ax2.set_ylim(-6, 6)
    ax3.set_xlim(-6, 6)
    ax3.set_ylim(-6, 6)
    # ax1.scatter(x, y, s = 100, c = altColors, cmap = plt.cm.jet_r)
    ax1.scatter(x, y, s=100, c=colorsDelta)
    ax2.scatter(x, y, s=100, c=colorsTheta)
    ax3.scatter(x, y, s=100, c=colorsAlpha)

    elapsed_time = time.time() - start_time
Ejemplo n.º 60
0
 def test_no_detrending(self):
     x = np.arange(10, dtype=np.float64) + 0.04
     f1, p1 = welch(x, nperseg=10, detrend=False)
     f2, p2 = welch(x, nperseg=10, detrend=lambda x: x)
     assert_allclose(f1, f2, atol=1e-15)
     assert_allclose(p1, p2, atol=1e-15)