예제 #1
0
def cross_wavelet(signal_1, signal_2, period, mother='morlet'):

    signal_1 = (signal_1 - signal_1.mean()) / signal_1.std()  # Normalizing
    signal_2 = (signal_2 - signal_2.mean()) / signal_2.std()  # Normalizing

    W12, cross_coi, freq, signif = wavelet.xwt(signal_1,
                                               signal_2,
                                               period,
                                               dj=1 / 100,
                                               s0=-1,
                                               J=-1,
                                               significance_level=0.95,
                                               wavelet=mother,
                                               normalize=True)

    cross_power = np.abs(W12)**2
    cross_sig = np.ones([1, signal_1.size]) * signif[:, None]
    cross_sig = cross_power / cross_sig
    cross_period = 1 / freq

    WCT, aWCT, corr_coi, freq, sig = wavelet.wct(signal_1,
                                                 signal_2,
                                                 period,
                                                 dj=1 / 100,
                                                 s0=-1,
                                                 J=-1,
                                                 sig=False,
                                                 significance_level=0.95,
                                                 wavelet=mother,
                                                 normalize=True)

    cor_sig = np.ones([1, signal_1.size]) * sig[:, None]
    cor_sig = np.abs(WCT) / cor_sig
    cor_period = 1 / freq
    t1 = np.linspace(0, period * signal_1.size, signal_1.size)
    idx = find_closest(cor_period, corr_coi.max())

    t1 /= 60
    cross_period /= 60
    cor_period /= 60
    cross_coi /= 60
    corr_coi /= 60

    return W12, WCT, aWCT, cor_period, corr_coi, cor_sig, idx, t1
# Due to the difference in the time series, the second signal 
# has to be trimmed for the XWT process.
s2 = s2[np.argwhere((t2 >= min(t1)) & (t2 <= max(t1))).flatten()]

''' Calculate the cross wavelet transform (XWT). 
The XWT finds regions in time frequency space where the time series
show high common power. Torrence and Compo (1998) state that the 
percent point function -- PPF (inverse of the 
cumulative distribution function) -- of a chi-square distribution 
at 95% confidence and two degrees of freedom is Z2(95%)=3.999. 
However, calculating the PPF using chi2.ppf gives Z2(95%)=5.991. 
To ensure similar significance intervals as in Grinsted et al. (2004),
one has to use confidence of 86.46%. '''
W12, cross_coi, freq, signif = wavelet.xwt(s1, s2, dt,
                                           dj=1/12, s0=-1, J=-1,
                                           significance_level=0.8646,
                                           wavelet='morlet',
                                           normalize=True)

cross_power = np.abs(W12)**2
cross_sig = np.ones([1, n]) * signif[:, None]
cross_sig = cross_power / cross_sig  # Power is significant where ratio > 1
cross_period = 1/freq



'''Calculate the wavelet coherence (WTC).
The WTC finds regions in time frequency space where the
two time seris co-vary, but do not necessarily have high power.'''
WCT, aWCT, corr_coi, freq, sig = wavelet.wct(s1, s2, dt,
                                             dj=1/12, s0=-1, J=-1,
예제 #3
0
def feature_gen(s1, s2, Mean, Std):

    #time domain features
    f_t1 = np.max(s1)
    f_t2 = np.min(s1)
    f_t3 = np.mean(s1)
    f_t4 = np.std(s1)
    f_t5 = f_t1 - f_t2
    f_t6 = np.percentile(s1, 25)
    f_t7 = np.percentile(s1, 50)
    f_t8 = np.percentile(s1, 75)
    f_t9 = skew(s1)
    f_t10 = kurtosis(s1)

    f_t11 = np.mean(np.absolute(s1))
    f_t12 = np.where(np.diff(np.sign([i for i in s1
                                      if i])))[0].shape[0]  #zero crossings
    f_t13 = np.where(np.diff(np.sign([i for i in np.gradient(s1)
                                      if i])))[0].shape[0]  #slope sign change

    s1 = (s1 - Mean) / Std  #pre-processing now
    dt = 1
    W_complex, _, _, _ = wavelet.xwt(s1, s2, dt, dj=1 / DJ)
    W = np.abs(W_complex)  #row->scale, col->time
    phi = np.abs(np.angle(W_complex))

    assert (phi.shape == W_complex.shape)

    total_scales = W.shape[0]
    total_time = W.shape[1]

    accum, accum_sq = get_sums(W)
    accum_phase, accum_sq_phase = get_sums(phi)

    phi_sum = np.sum(phi)
    W_sum = np.sum(W)

    #frequency domain features
    f1 = accum / W_sum
    f2 = np.sqrt(accum_sq / W_sum)
    f3 = W_sum / np.max(W)

    s_min, t_min = np.unravel_index(W.argmin(), W.shape)
    s_max, t_max = np.unravel_index(W.argmax(), W.shape)
    x = total_scales * total_time

    eps = 1e-5
    f4 = W_sum / (x + eps)  #adding small eps to avoid divide by zero error
    f5 = np.sqrt((np.sum((np.square(f4 - W)))) / (x + eps))

    f6 = s_max
    f7 = t_max
    f8 = s_min
    f81 = t_min

    f9 = np.sum(
        np.multiply(
            W,
            np.arange(1, total_scales + 1).reshape(-1, 1) *
            np.ones_like(W))) / (x + eps)
    f10 = np.sum(np.square(W))
    f11 = f10 / (x + eps)
    f12 = np.sqrt(np.sum(np.square(W)) / (x + eps))

    w = np.array(W)
    s = 0
    for i in range(1, total_scales):
        s += np.sum(np.square(w[i, :] - w[i - 1, :]))

    consec_scale_diff = np.sqrt(s)

    f14 = consec_scale_diff
    f15 = f14 / (x + eps)
    f16 = np.sqrt((f14**2) / (x + eps))
    f17 = np.log10(f14)
    f18 = W_sum
    f19 = accum_phase / phi_sum
    f20 = np.sqrt(accum_sq_phase / phi_sum)
    f21 = phi_sum
    f22 = phi_sum / (np.max(phi))
    f23 = phi_sum / (x + eps)
    f24 = np.sqrt((np.sum(np.square((f22 - phi)))) / (x + eps))
    f25 = np.sum(
        np.multiply(
            phi,
            np.arange(1, total_scales + 1).reshape(-1, 1) * np.ones_like(phi)))

    f26 = np.sqrt(np.sum(
        np.square(s1 - s2)))  #euclidean distance between s1 and mcv ?
    f27 = cosine_similarity(s1.reshape(1, -1),
                            s2.reshape(1, -1),
                            dense_output=True).reshape(1, 1)[0][0]

    corr = correntropy(s1, s2)
    f28 = np.mean(corr)
    f29 = kurtosis(corr)
    f30 = skew(corr)
    f31 = moment(corr, moment=2)
    f32 = moment(corr, moment=3)
    f33 = trim_mean(corr, 0.1)

    f = [
        f_t1, f_t2, f_t3, f_t4, f_t5, f_t6, f_t7, f_t8, f_t9, f_t10, f_t11,
        f_t12, f_t13, f1, f2, f3, f4, f5, f6, f7, f8, f81, f9, f10, f11, f12,
        f14, f15, f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, f27,
        f28, f29, f30, f31, f32, f33
    ]

    return np.array(f)
예제 #4
0
파일: sample_xwt.py 프로젝트: regeirk/pycwt
# II. Cross-wavelet transform
# ===========================

# Due to the difference in the time series, the second signal has to be
# trimmed for the XWT process.
s2 = s2[np.argwhere((t2 >= min(t1)) & (t2 <= max(t1))).flatten()]

# Calculate the cross wavelet transform (XWT). The XWT finds regions in time
# frequency space where the time series show high common power. Torrence and
# Compo (1998) state that the percent point function -- PPF (inverse of the
# cumulative distribution function) -- of a chi-square distribution at 95%
# confidence and two degrees of freedom is Z2(95%)=3.999. However, calculating
# the PPF using chi2.ppf gives Z2(95%)=5.991. To ensure similar significance
# intervals as in Grinsted et al. (2004), one has to use confidence of 86.46%.
W12, cross_coi, freq, signif = wavelet.xwt(s1, s2, dt, dj=1/12, s0=-1, J=-1,
                                           significance_level=0.8646,
                                           wavelet='morlet', normalize=True)

cross_power = np.abs(W12)**2
cross_sig = np.ones([1, n]) * signif[:, None]
cross_sig = cross_power / cross_sig  # Power is significant where ratio > 1
cross_period = 1/freq

# Calculate the wavelet coherence (WTC). The WTC finds regions in time
# frequency space where the two time seris co-vary, but do not necessarily have
# high power.
WCT, aWCT, corr_coi, freq, sig = wavelet.wct(s1, s2, dt, dj=1/12, s0=-1, J=-1,
                                             significance_level=0.8646,
                                             wavelet='morlet', normalize=True,
                                             cache=True)
def plot_cross_wavelet(wave1,
                       wave2,
                       sample_times,
                       min_freq=1,
                       max_freq=256,
                       sig=False,
                       ax=None,
                       title="Cross-Wavelet",
                       plot_coi=True,
                       plot_period=False,
                       resolution=12,
                       all_arrows=True,
                       quiv_x=5,
                       quiv_y=24,
                       block=None):
    """
    Plot cross wavelet correlation between wave1 and wave2 using pycwt.

    TODO Fix this function
    TODO also test out sig on a large dataset

    Parameters
    ----------
    wave1 : np.ndarray
        The values of the first waveform.
    wave2 : np.ndarray
        The values of the second waveform.
    sample_times : np.ndarray
        The times at which waveform samples occur.
    min_freq : float
        Supposed to be minimum frequency, but not quite working.
    max_freq : float
        Supposed to be max frequency, but not quite working.
    sig : bool, default False
        Optional Should significance of waveform coherence be calculated.
    ax : plt.axe, default None
        Optional ax object to plot into.
    title : str, default "Wavelet Coherence"
        Optional title for the graph
    plot_coi : bool, default True
        Should the cone of influence be plotted
    plot_period : bool
        Should the y-axis be in period or in frequency (Hz)
    resolution : int
        How many wavelets should be at each level of the graph
    all_arrows : bool
        Should phase arrows be plotted uniformly or only at high coherence
    quiv_x : float
        sets quiver window in time domain in seconds
    quiv_y : float
        sets number of quivers evenly distributed across freq limits
    block : [int, int]
        Plots only points between ints.

    Returns
    -------
    tuple : (fig, result)
        Where fig is a matplotlib Figure
        and result is a tuple consisting of WCT, aWCT, coi, freq, sig
        WCT - 2D numpy array with coherence values
        aWCT - 2D numpy array with same shape as aWCT indicating phase angles
        coi - 1D numpy array with a frequency value for each time
        freq - 1D numpy array with the frequencies wavelets were calculated at
        sig - 2D numpy array indicating where data is significant by monte carlo

    """
    t = np.asarray(sample_times)
    dt = np.mean(np.diff(t))
    # Set up the scales to match min max input frequencies
    dj = resolution
    s0 = 1 / max_freq
    if s0 < (2 * dt):
        s0 = 2 * dt
    max_J = 1 / min_freq
    J = dj * np.int(np.round(np.log2(max_J / np.abs(s0))))

    # Do the actual calculation
    W12, coi, freq, signif = wavelet.xwt(
        wave1,
        wave2,
        dt,  # Fixed params
        dj=(1.0 / dj),
        s0=s0,
        J=J,
        significance_level=0.8646,
        normalize=True,
    )

    cross_power = np.abs(W12)**2

    if np.max(W12) > 6**2 or np.min(W12) < 0:
        print('W12 was out of range: min{},max{}'.format(
            np.min(W12), np.max(W12)))
        cross_power = np.clip(cross_power, 0, 6**2)
    # print('cross max:', np.max(cross_power))
    # print('cross min:', np.min(cross_power))

    cross_sig = np.ones([1, len(t)]) * signif[:, None]
    cross_sig = cross_power / cross_sig  # Power is significant where ratio > 1

    # Convert frequency to period if necessary
    if plot_period:
        y_vals = np.log2(1 / freq)
    if not plot_period:
        y_vals = np.log2(freq)

    if ax is None:
        fig, ax = plt.subplots()
    else:
        fig = None

    # Set the x and y axes of the plot
    extent_corr = [t.min(), t.max(), 0, max(y_vals)]

    # Fill the plot with the magnitude squared correlation values
    # That is, MSC = abs(Pxy) ^ 2 / (Pxx * Pyy)
    # TODO I think this might be the wrong way to plot this
    # It assumes that the samples are linearly spaced
    im = NonUniformImage(ax, interpolation='bilinear', extent=extent_corr)

    if plot_period:
        im.set_data(t, y_vals, cross_power)
    else:
        im.set_data(t, y_vals[::-1], cross_power[::-1, :])
    ax.images.append(im)
    # pcm = ax.pcolormesh(WCT)

    # Plot the cone of influence - Periods greater than
    # those are subject to edge effects.
    if plot_coi:
        # Performed by plotting a polygon
        x_positions = np.zeros(shape=(len(t), ))
        x_positions = t

        y_positions = np.zeros(shape=(len(t), ))
        if plot_period:
            y_positions = np.log2(coi)
        else:
            y_positions = np.log2(1 / coi)

        ax.plot(x_positions, y_positions, 'w--', linewidth=2, c="w")

    # Plot the significance level contour plot
    if sig:
        ax.contour(t,
                   y_vals,
                   cross_sig, [-99, 1],
                   colors='k',
                   linewidths=2,
                   extent=extent_corr)

    # Add limits, titles, etc.
    ax.set_ylim(min(y_vals), max(y_vals))

    if block:
        ax.set_xlim(t[block[0]], t[int(block[1] * 1 / dt)])
    else:
        ax.set_xlim(t.min(), t.max())

    # TODO split graph into smaller time chunks
    # Test for smaller timescale
    # quiv_x = 1

    # Add the colorbar to the figure
    if fig is not None:
        fig.colorbar(im)
    else:
        plt.colorbar(im, ax=ax, use_gridspec=True)

    if plot_period:
        y_ticks = np.linspace(min(y_vals), max(y_vals), 8)
        # TODO improve ticks
        y_ticks = [
            np.log2(x)
            for x in [0.004, 0.008, 0.016, 0.032, 0.064, 0.125, 0.25, 0.5, 1]
        ]
        y_labels = [str(x) for x in (np.round(np.exp2(y_ticks), 3))]
    else:
        y_ticks = np.linspace(min(y_vals), max(y_vals), 8)
        # TODO improve ticks
        # y_ticks = [np.log2(x) for x in [256, 128, 64, 32, 16, 8, 4, 2, 1]]
        y_ticks = [np.log2(x) for x in [64, 32, 16, 8, 4, 2, 1]]
        y_labels = [str(x) for x in (np.round(np.exp2(y_ticks), 3))]
    plt.yticks(y_ticks, y_labels)
    ax.set_title(title)
    ax.set_xlabel("Time (s)")

    if plot_period:
        ax.set_ylabel("Period")
    else:
        ax.set_ylabel("Frequency (Hz)")

    return (fig, [W12, coi, freq, sig])
예제 #6
0
    def cross_wavelet(self, signal_1, signal_2, mother='morlet', plot=True):

        signal_1 = (signal_1 - signal_1.mean()) / signal_1.std()    # Normalizing
        signal_2 = (signal_2 - signal_2.mean()) / signal_2.std()    # Normalizing

        W12, cross_coi, freq, signif = wavelet.xwt(signal_1, signal_2, self.period, dj=1/100, s0=-1, J=-1,
                                             significance_level=0.95, wavelet=mother,
                                             normalize=True)

        cross_power = np.abs(W12)**2
        cross_sig = np.ones([1, signal_1.size]) * signif[:, None]
        cross_sig = cross_power / cross_sig
        cross_period = 1/freq

        WCT, aWCT, corr_coi, freq, sig = wavelet.wct(signal_1, signal_2, self.period, dj=1/100, s0=-1, J=-1,
                                                sig=False,significance_level=0.95, wavelet=mother,
                                                normalize=True)

        cor_sig = np.ones([1, signal_1.size]) * sig[:, None]
        cor_sig = np.abs(WCT) / cor_sig
        cor_period = 1/freq

        angle = 0.5 * np.pi - aWCT
        u, v = np.cos(angle), np.sin(angle)


        t1 = np.linspace(0,self.period*signal_1.size,signal_1.size)

        ## indices for stuff
        idx = self.find_closest(cor_period,corr_coi.max())

        ## Into minutes
        t1 /= 60
        cross_period /= 60
        cor_period /= 60
        cross_coi /= 60
        corr_coi /= 60

        fig1, ax1 = plt.subplots(nrows=1,ncols=1, sharex=True, sharey=True, figsize=(12,12))
        extent_cross = [t1.min(),t1.max(),0,max(cross_period)]
        extent_corr =  [t1.min(),t1.max(),0,max(cor_period)]
        im1 = NonUniformImage(ax1, interpolation='nearest', extent=extent_cross)
        im1.set_cmap('cubehelix')
        im1.set_data(t1, cross_period[:idx], cross_power[:idx,:])
        ax1.images.append(im1)
        ax1.contour(t1, cross_period[:idx], cross_sig[:idx,:], [-99, 1], colors='k', linewidths=2, extent=extent_cross)
        ax1.fill(np.concatenate([t1, t1[-1:]+self.period, t1[-1:]+self.period,t1[:1]-self.period, t1[:1]-self.period]),
                (np.concatenate([cross_coi,[1e-9], cross_period[-1:], cross_period[-1:], [1e-9]])),
                'k', alpha=0.3,hatch='x')
        ax1.set_title('Cross-Wavelet')
#        ax1.quiver(t1[::3], cross_period[::3], u[::3, ::3],
#                  v[::3, ::3], units='width', angles='uv', pivot='mid',
#                  linewidth=1.5, edgecolor='k', headwidth=10, headlength=10,
#                  headaxislength=5, minshaft=2, minlength=5)
        ax1.set_ylim(([min(cross_period), cross_period[idx]]))
        ax1.set_xlim(t1.min(),t1.max())

        fig2, ax2 = plt.subplots(nrows=1,ncols=1, sharex=True, sharey=True, figsize=(12,12))
        fig2.subplots_adjust(right=0.8)
        cbar_ax_1 = fig2.add_axes([0.85, 0.05, 0.05, 0.35])
        im2 = NonUniformImage(ax2, interpolation='nearest', extent=extent_corr)
        im2.set_cmap('cubehelix')
        im2.set_data(t1, cor_period[:idx], np.log10(WCT[:idx,:]))
        ax2.images.append(im2)
        ax2.contour(t1, cor_period[:idx], cor_sig[:idx,:], [-99, 1], colors='k', linewidths=2, extent=extent_corr)
        ax2.fill(np.concatenate([t1, t1[-1:]+self.period, t1[-1:]+self.period,t1[:1]-self.period, t1[:1]-self.period]),
                (np.concatenate([corr_coi,[1e-9], cor_period[-1:], cor_period[-1:], [1e-9]])),
                'k', alpha=0.3,hatch='x')
        ax2.set_title('Cross-Correlation')
#        ax2.quiver(t1[::3], cor_period[::3], u[::3,::3], v[::3,::3],
#                   units='height', angles='uv', pivot='mid',linewidth=1.5, edgecolor='k',
#                   headwidth=10, headlength=10, headaxislength=5, minshaft=2, minlength=5)
        ax2.set_ylim(([min(cor_period), cor_period[idx]]))
        ax2.set_xlim(t1.min(),t1.max())
        fig2.colorbar(im2, cax=cbar_ax_1)

        plt.show()

        plt.figure(figsize=(12,12))
        im3= plt.imshow(np.rad2deg(aWCT), origin='lower',interpolation='nearest', cmap='seismic', extent=extent_corr)
        plt.fill(np.concatenate([t1, t1[-1:]+self.period, t1[-1:]+self.period,t1[:1]-self.period, t1[:1]-self.period]),
                (np.concatenate([corr_coi,[1e-9], cor_period[-1:], cor_period[-1:], [1e-9]])),
                'k', alpha=0.3,hatch='x')
        plt.ylim(([min(cor_period), cor_period[idx]]))
        plt.xlim(t1.min(),t1.max())
        plt.colorbar(im3)
        plt.show()


        return