Exemplo n.º 1
0
    def __init__(self, signal, time, frequency=100e3, wavelet='Mexican'):
        """

        Parameters
        ----------
        signal : ndarray
            Signal to be analyzed
        time : ndarray
            Time basis
        frequency : Float
            Fourier frequency for the analysis
        wavelet : :obj: `str`
            String indicating the type of wavelet used
            for the analysis. Default is 'Mexican'

        """

        if wavelet == 'Mexican':
            self.mother = wav.MexicanHat()
        elif wavelet == 'DOG1':
            self.mother = wav.DOG(m=1)
        elif wavelet == 'Morlet':
            self.mother = wav.Morlet()
        else:
            print 'Not a valid wavelet using Mexican'
            self.mother = wav.MexicanHat()
        # inizializza l'opportuna scala
        self.fr = frequency
        self.scale = 1. / self.mother.flambda() / self.fr
        self.sig = copy.deepcopy(signal)
        self.nsamp = signal.size
        self.time = copy.deepcopy(time)
        self.dt = (time.max() - time.min()) / (self.nsamp - 1)
        self.Fs = 1. / self.dt
        self.cwt()
def graph_wavelet(data_xs, title, lims, font = 11, params = default_params):
    a_lims, b_lims, d_lims = lims
    plt.rcParams.update({'font.size': font})
    return_data = {}
    
    N = len(data_xs)
    dt = (2*params['per_pixel'])/N #This is how much cm each pixel equals
    t = np.arange(0, N) * dt
    t = t - np.mean(t)
    t0 = 0
    per_min = params['min_per']
    per_max = params['max_per']
    units = params['units']
    sx = params['sx']
    octaves = params['octaves']
    dj = 1/params['suboctaves'] #suboctaves
    order = params['order']
    
    var, std, dat_norm = detrend(data_xs)
    mother = cwt.DOG(order) #This is the Mother Wavelet
    s0 = sx * dt #This is the starting scale, which in out case is two pixels or 0.04cm/40um\
    J = octaves/dj #This is powers of two with dj suboctaves
    
    return_data['var'] = var
    return_data['std'] = std
    
    try:
        alpha, _, _ = cwt.ar1(dat_norm) #This calculates the Lag-1 autocorrelation for red noise
    except: 
        alpha = 0.95
            
    wave, scales, freqs, coi, fft, fftfreqs = cwt.cwt(dat_norm, dt, dj, s0, J,
                                                              mother)
    return_data['scales'] = scales
    return_data['freqs'] = freqs
    return_data['fft'] = fft
    iwave = cwt.icwt(wave, scales, dt, dj, mother) * std
        
    power = (np.abs(wave)) ** 2
    fft_power = np.abs(fft) ** 2
    period = 1 / freqs
    power /= scales[:, None] #This is an option suggested by Liu et. al.
    

    #Next we calculate the significance of the power spectra. Significane where power / sig95 > 1
    signif, fft_theor = cwt.significance(1.0, dt, scales, 0, alpha,
                                             significance_level=0.95,
                                             wavelet=mother)
    sig95 = np.ones([1, N]) * signif[:, None]
    sig95 = power / sig95
    
    glbl_power = power.mean(axis=1)
    dof = N - scales  # Correction for padding at edges
    glbl_signif, tmp = cwt.significance(var, dt, scales, 1, alpha,
                                            significance_level=0.95, dof=dof,
                                            wavelet=mother)
    
    sel = find((period >= per_min) & (period < per_max))
    Cdelta = mother.cdelta
    scale_avg = (scales * np.ones((N, 1))).transpose()
    scale_avg = power / scale_avg  # As in Torrence and Compo (1998) equation 24
    scale_avg = var * dj * dt / Cdelta * scale_avg[sel, :].sum(axis=0)
    scale_avg_signif, tmp = cwt.significance(var, dt, scales, 2, alpha,
                                                 significance_level=0.95,
                                                 dof=[scales[sel[0]],
                                                      scales[sel[-1]]],
                                                 wavelet=mother)
    
    
    # Prepare the figure
    plt.close('all')
    plt.ioff()
    figprops = dict(figsize=(11, 11), dpi=72)
    fig = plt.figure(**figprops)
    
    wx = plt.axes([0.77, 0.75, 0.2, 0.2])
    imz = 0
    for idxy in range(0,len(period), 10):
        wx.plot(t, mother.psi(t / period[idxy]) + imz, linewidth = 1.5)
        imz+=1
        wx.xaxis.set_ticklabels([])
    
    ax = plt.axes([0.1, 0.75, 0.65, 0.2])
    ax.plot(t, data_xs, 'k', linewidth=1.5)
    ax.plot(t, iwave, '-', linewidth=1, color=[0.5, 0.5, 0.5])
    ax.plot(t, dat_norm, '--', linewidth=1.5, color=[0.5, 0.5, 0.5])
    if a_lims != None:
        ax.set_ylim([-a_lims, a_lims])
    ax.set_title('a) {}'.format(title))
    ax.set_ylabel(r'Displacement [{}]'.format(units))
    #ax.set_ylim([-20,20])

    bx = plt.axes([0.1, 0.37, 0.65, 0.28], sharex=ax)
    levels = [0.0625, 0.125, 0.25, 0.5, 1, 2, 4, 8, 16]
    bx.contourf(t, np.log2(period), np.log2(power), np.log2(levels),
                extend='both', cmap=plt.cm.viridis)
    extent = [t.min(), t.max(), 0, max(period)]
    bx.contour(t, np.log2(period), sig95, [-99, 1], colors='k', linewidths=2,
               extent=extent)
    bx.fill(np.concatenate([t, t[-1:] + dt, t[-1:] + dt,
                               t[:1] - dt, t[:1] - dt]),
            np.concatenate([np.log2(coi), [1e-9], np.log2(period[-1:]),
                               np.log2(period[-1:]), [1e-9]]),
            'k', alpha=0.3, hatch='x')
    bx.set_title('b) {} Octaves Wavelet Power Spectrum [{}({})]'.format(octaves, mother.name, order))
    bx.set_ylabel('Period (cm)')
    #
    Yticks = 2 ** np.arange(np.ceil(np.log2(period.min())),
                               np.ceil(np.log2(period.max())))
    bx.set_yticks(np.log2(Yticks))
    bx.set_yticklabels(Yticks)
    
    # Third sub-plot, the global wavelet and Fourier power spectra and theoretical
    # noise spectra. Note that period scale is logarithmic.
    cx = plt.axes([0.77, 0.37, 0.2, 0.28], sharey=bx)
    cx.plot(glbl_signif, np.log2(period), 'k--')
    cx.plot(var * fft_theor, np.log2(period), '--', color='#cccccc')
    cx.plot(var * fft_power, np.log2(1./fftfreqs), '-', color='#cccccc',
            linewidth=1.)
    
    return_data['global_power'] = var * glbl_power
    return_data['fourier_spectra'] = var * fft_power
    return_data['per'] = np.log2(period)
    return_data['amp'] = np.log2(1./fftfreqs)
    
    cx.plot(var * glbl_power, np.log2(period), 'k-', linewidth=1.5)
    cx.set_title('c) Power Spectrum')
    cx.set_xlabel(r'Power [({})^2]'.format(units))
    if b_lims != None:
        cx.set_xlim([0,b_lims])
    #cx.set_xlim([0,max(glbl_power.max(), var*fft_power.max())])
    #print(max(glbl_power.max(), var*fft_power.max()))
    cx.set_ylim(np.log2([period.min(), period.max()]))
    cx.set_yticks(np.log2(Yticks))
    cx.set_yticklabels(Yticks)
    return_data['yticks'] = Yticks
    
    plt.setp(cx.get_yticklabels(), visible=False)
    
    # Fourth sub-plot, the scale averaged wavelet spectrum.
    dx = plt.axes([0.1, 0.07, 0.65, 0.2], sharex=ax)
    dx.axhline(scale_avg_signif, color='k', linestyle='--', linewidth=1.)
    dx.plot(t, scale_avg, 'k-', linewidth=1.5)
    dx.set_title('d) {}--{} cm scale-averaged power'.format(per_min, per_max))
    dx.set_xlabel('Displacement (cm)')
    dx.set_ylabel(r'Average variance [{}]'.format(units))
    ax.set_xlim([t.min(), t.max()])
    if d_lims != None:
        dx.set_ylim([0,d_lims])
    plt.savefig("C:\pyscripts\wavelet_analysis\Calibrated Images\{}".format(title))
    return fig, return_data
Exemplo n.º 3
0
import numpy as np
from scipy import signal
from scipy import interpolate
import pycwt as wavelet
from statsmodels.tsa.ar_model import AutoReg

mother_wave_dict = {
    'gaussian': wavelet.DOG(),
    'paul': wavelet.Paul(),
    'mexican_hat': wavelet.MexicanHat()
}


def calculate_power(freq, pow, fmin, fmax):
    """
    Compute the power within the band range

    Parameters
    ----------
    freq: array-like
        list of all frequencies need to be computed
    pow: array-like
        the power of relevant frequencies
    fmin: float
        lower bound of the selected band
    fmax: float
        upper bound of the selected band

    Returns
    -------
        :float
Exemplo n.º 4
0
def parse_frames(image_file, sig=0.95):
    """
    
    """
    cap = cv2.VideoCapture(image_file)
    if verbose: print("Video successfully loaded")
    FRAME_COUNT = int(cap.get(cv2.CAP_PROP_FRAME_COUNT))
    FPS = cap.get(cv2.CAP_PROP_FPS)
    if verbose > 1:
        FRAME_HEIGHT = cap.get(cv2.CAP_PROP_FRAME_HEIGHT)
        FRAME_WIDTH = cap.get(cv2.CAP_PROP_FRAME_WIDTH)
        print(
            "INFO: \n Frame count: ",
            FRAME_COUNT,
            "\n",
            "FPS: ",
            FPS,
            " \n",
            "FRAME_HEIGHT: ",
            FRAME_HEIGHT,
            " \n",
            "FRAME_WIDTH: ",
            FRAME_WIDTH,
            " \n",
        )

    directory = os.getcwd(
    ) + '\\analysis\\{}_{}_{}_{}({})_{}_{}_scaled\\'.format(
        date, trial_type, name, wavelet, order, per_min, per_max)
    if not os.path.exists(directory):
        os.makedirs(directory)
    made = False
    frame_idx = 0
    idx = 0
    dropped = 0
    skip = True
    thresh = None

    df_wav = pd.DataFrame()
    df_auc = pd.DataFrame()
    df_for = pd.DataFrame()
    df_pow = pd.DataFrame()

    for i in range(FRAME_COUNT):
        a, img = cap.read()
        if a:
            frame_idx += 1

            if made == False:
                #first we need to manually determine the boundaries and angle
                res = bg.manual_format(img)
                #print(res)
                x, y, w, h, angle = res
                horizon_begin = x
                horizon_end = x + w
                vert_begin = y
                vert_end = y + h
                #scale_array = np.zeros((FRAME_COUNT, abs(horizon_begin - horizon_end)))
                #area_time = np.zeros((FRAME_COUNT))
                #df[']
                print("Now Select the Red dot")
                red_res = bg.manual_format(img, stop_sign=True)
                red_x, red_y, red_w, red_h = red_res
                box_h_begin = red_x
                box_h_end = red_x + red_w
                box_v_begin = red_y
                box_v_end = red_y + red_h
                made = True
                #dims = (vert_begin, vert_end, horizon_begin, horizon_end)

            real_time = i / FPS
            rows, cols, chs = img.shape
            M = cv2.getRotationMatrix2D((cols / 2, rows / 2), angle, 1)
            rot_img = cv2.warpAffine(img, M, (cols, rows))
            roi = rot_img[vert_begin:vert_end, horizon_begin:horizon_end, :]

            red_box = img[box_v_begin:box_v_end, box_h_begin:box_h_end, 2]
            if thresh == None:
                thresh = np.mean(red_box)
            #print(np.mean(red_box))
            percent_drop = 1 - (np.mean(red_box) / thresh)
            print(percent_drop)
            if percent_drop >= 0.18:
                #cv2.imshow("Red Image", red_box)
                #cv2.waitKey(0)
                skip = False

            if skip:
                if verbose >= 1:
                    print('Frame is skipped {} / {}'.format(
                        frame_idx, FRAME_COUNT))
                continue

            if verbose >= 1:
                print('Processing frame {} / {}'.format(
                    frame_idx, FRAME_COUNT))

            idx += 1
            begin_code, data_line = extract_frame(roi)

            #We need to detrend the data before sending it away
            N = len(data_line)
            dt = su / N
            t = np.arange(0, N) * dt
            t = t - np.mean(t)

            var, std, dat_norm = detrend(data_line)
            ###################################################################
            if wavelet == 'DOG':
                mother = cwt.DOG(order)
            elif wavelet == 'Paul':
                mother = cwt.Paul(order)
            elif wavelet == 'Morlet':
                mother = cwt.Morlet(order)
            elif wavelet == 'MexicanHat':
                mother = cwt.MexicanHat(order)

            s0 = 4 * dt
            try:
                alpha, _, _ = cwt.ar1(dat_norm)
            except:
                alpha = 0.95

            wave, scales, freqs, coi, fft, fftfreqs = cwt.cwt(
                dat_norm, dt, dj, s0, J, mother)

            iwave = cwt.icwt(
                wave, scales, dt, dj,
                mother) * std  #This is a reconstruction of the wave

            power = (np.abs(wave))**2  #This is the power spectra
            fft_power = np.abs(fft)**2  #This is the fourier power
            period = 1 / freqs  #This is the periods of the wavelet analysis in cm
            power /= scales[:,
                            None]  #This is an option suggested by Liu et. al.

            #Next we calculate the significance of the power spectra. Significane where power / sig95 > 1
            signif, fft_theor = cwt.significance(1.0,
                                                 dt,
                                                 scales,
                                                 0,
                                                 alpha,
                                                 significance_level=0.95,
                                                 wavelet=mother)
            sig95 = np.ones([1, N]) * signif[:, None]
            sig95 = power / sig95

            #This is the significance of the global wave
            glbl_power = power.mean(axis=1)
            dof = N - scales  # Correction for padding at edges
            glbl_signif, tmp = cwt.significance(var,
                                                dt,
                                                scales,
                                                1,
                                                alpha,
                                                significance_level=0.95,
                                                dof=dof,
                                                wavelet=mother)

            sel = find((period >= per_min) & (period < per_max))
            Cdelta = mother.cdelta
            scale_avg = (scales * np.ones((N, 1))).transpose()
            scale_avg = power / scale_avg  # As in Torrence and Compo (1998) equation 24
            #scale_avg = var * dj * dt / Cdelta * scale_avg[sel, :].sum(axis=0)

            #scale_array[i,:] = scale_array[i,:]/np.max(scale_array[i,:])
            #data_array[i,:] = data_array[i,:]/np.max(data_array[i,:])

            scale_avg = var * dj * dt / Cdelta * scale_avg[sel, :].sum(axis=0)
            scale_avg_signif, tmp = cwt.significance(
                var,
                dt,
                scales,
                2,
                alpha,
                significance_level=0.95,
                dof=[scales[sel[0]], scales[sel[-1]]],
                wavelet=mother)
            Yticks = 2**np.arange(np.ceil(np.log2(period.min())),
                                  np.ceil(np.log2(period.max())))

            plt.close('all')
            plt.ioff()
            figprops = dict(figsize=(11, 8), dpi=72)
            fig = plt.figure(**figprops)

            wx = plt.axes([0.77, 0.75, 0.2, 0.2])
            imz = 0
            for idxy in range(0, len(period), 10):
                wx.plot(t, mother.psi(t / period[idxy]) + imz, linewidth=1.5)
                imz += 1
            wx.xaxis.set_ticklabels([])
            #wx.set_ylim([-10,10])
            # First sub-plot, the original time series anomaly and inverse wavelet
            # transform.
            ax = plt.axes([0.1, 0.75, 0.65, 0.2])
            ax.plot(t,
                    data_line - np.mean(data_line),
                    'k',
                    label="Original Data")
            ax.plot(t,
                    iwave,
                    '-',
                    linewidth=1,
                    color=[0.5, 0.5, 0.5],
                    label="Reconstructed wave")
            ax.plot(t,
                    dat_norm,
                    '--k',
                    linewidth=1.5,
                    color=[0.5, 0.5, 0.5],
                    label="Denoised Wave")
            ax.set_title(
                'a) {:10.2f} from beginning of trial.'.format(real_time))
            ax.set_ylabel(r'{} [{}]'.format("Amplitude", unit))
            ax.legend(loc=1)
            ax.set_ylim([-200, 200])
            #If the non-serrated section, bounds are 200 -
            # Second sub-plot, the normalized wavelet power spectrum and significance
            # level contour lines and cone of influece hatched area. Note that period
            # scale is logarithmic.
            bx = plt.axes([0.1, 0.37, 0.65, 0.28], sharex=ax)
            levels = [0.0625, 0.125, 0.25, 0.5, 1, 2, 4, 8, 16]
            cont = bx.contourf(t,
                               np.log2(period),
                               np.log2(power),
                               np.log2(levels),
                               extend='both',
                               cmap=plt.cm.viridis)
            extent = [t.min(), t.max(), 0, max(period)]
            bx.contour(t,
                       np.log2(period),
                       sig95, [-99, 1],
                       colors='k',
                       linewidths=2,
                       extent=extent)
            bx.fill(np.concatenate(
                [t, t[-1:] + dt, t[-1:] + dt, t[:1] - dt, t[:1] - dt]),
                    np.concatenate([
                        np.log2(coi), [1e-9],
                        np.log2(period[-1:]),
                        np.log2(period[-1:]), [1e-9]
                    ]),
                    'k',
                    alpha=0.3,
                    hatch='x')
            bx.set_title(
                'b) {} Octaves Wavelet Power Spectrum [{}({})]'.format(
                    octaves, mother.name, order))
            bx.set_ylabel('Period (cm)')
            #
            Yticks = 2**np.arange(np.ceil(np.log2(period.min())),
                                  np.ceil(np.log2(period.max())))
            bx.set_yticks(np.log2(Yticks))
            bx.set_yticklabels(Yticks)
            cbar = fig.colorbar(cont, ax=bx)
            # Third sub-plot, the global wavelet and Fourier power spectra and theoretical
            # noise spectra. Note that period scale is logarithmic.
            cx = plt.axes([0.77, 0.37, 0.2, 0.28], sharey=bx)
            cx.plot(glbl_signif, np.log2(period), 'k--')
            cx.plot(var * fft_theor, np.log2(period), '--', color='#cccccc')
            cx.plot(var * fft_power,
                    np.log2(1. / fftfreqs),
                    '-',
                    color='#cccccc',
                    linewidth=1.)
            cx.plot(var * glbl_power, np.log2(period), 'k-', linewidth=1.5)
            cx.set_title('c) Global Wavelet Spectrum')
            cx.set_xlabel(r'Power [({})^2]'.format(unit))
            #cx.set_xlim([0, (var*fft_theor).max()])
            plt.xscale('log')
            cx.set_ylim(np.log2([period.min(), period.max()]))
            cx.set_yticks(np.log2(Yticks))
            cx.set_yticklabels(Yticks)

            #if sig_array == []:
            yvals = np.linspace(Yticks.min(), Yticks.max(), len(period))

            plt.xscale('linear')
            plt.setp(cx.get_yticklabels(), visible=False)

            # Fourth sub-plot, the scale averaged wavelet spectrum.
            dx = plt.axes([0.1, 0.07, 0.65, 0.2], sharex=ax)
            dx.axhline(scale_avg_signif,
                       color='k',
                       linestyle='--',
                       linewidth=1.)
            dx.plot(t, scale_avg, 'k-', linewidth=1.5)
            dx.set_title('d) {}-{}cm scale-averaged power'.format(
                per_min, per_max))
            dx.set_xlabel('Distance from center(cm)')
            dx.set_ylabel(r'Average variance [{}]'.format(unit))
            #dx.set_ylim([0,500])
            ax.set_xlim([t.min(), t.max()])

            #plt.savefig(directory+'{}_analysis_frame-{}.png'.format(name, idx), bbox = 'tight')
            if verbose >= 2:
                print('*' * int((i / FRAME_COUNT) * 100))

            df_wav[real_time] = (pd.Series(dat_norm, index=t))
            df_pow[real_time] = (pd.Series(var * glbl_power,
                                           index=np.log2(period)))
            df_for[real_time] = (pd.Series(var * fft_power,
                                           index=np.log2(1. / fftfreqs)))
            df_auc[real_time] = [np.trapz(data_line)]

        else:
            print("Frame #{} has dropped".format(i))
            dropped += 1

    if verbose >= 1: print('All images saved')
    if verbose >= 1:
        print("{:10.2f} % of the frames have dropped".format(
            (dropped / FRAME_COUNT) * 100))

    #Plotting and saving tyhe

    row, cols = df_pow.shape
    time = np.arange(0, cols) / FPS

    plt.close('all')
    plt.ioff()
    plt.contourf(time, df_pow.index.tolist(), df_pow)
    plt.contour(time, df_pow.index.tolist(), df_pow)
    plt.title("Global Power over Time")
    plt.ylabel("Period[cm]")
    plt.xlabel("Time")
    cax = plt.gca()
    #plt.xscale('log')
    cax.set_ylim(np.log2([period.min(), period.max()]))
    cax.set_yticks(np.log2(Yticks))
    cax.set_yticklabels(Yticks)

    plt.savefig(directory + '{}_global_power-{}.png'.format(name, idx),
                bbox='tight')

    row, cols = df_for.shape
    time = np.arange(0, cols) / FPS
    plt.close('all')
    plt.ioff()
    plt.contourf(time, df_for.index.tolist(), df_for)
    plt.contour(time, df_for.index.tolist(), df_for)
    plt.title("Fourier Power over Time")
    plt.ylabel("Period[cm]")
    plt.xlabel("Time")
    cax = plt.gca()
    #plt.xscale('log')
    cax.set_ylim(np.log2([period.min(), period.max()]))
    cax.set_yticks(np.log2(Yticks))
    cax.set_yticklabels(Yticks)
    plt.savefig(directory + '{}_fourier_power-{}.png'.format(name, idx),
                bbox='tight')

    plt.close('all')
    plt.ioff()
    rows, cols = df_auc.shape
    time = np.arange(0, cols) / FPS
    plt.plot(time, df_auc.T)
    plt.xlabel("Time")
    plt.ylabel("Area under the curve in cm")
    plt.title("Area under the curve over time")
    plt.savefig(directory + '{}_area_under_curve-{}.png'.format(name, idx),
                bbox='tight')

    df_wav['Mean'] = df_wav.mean(axis=1)
    df_pow['Mean'] = df_pow.mean(axis=1)
    df_for['Mean'] = df_for.mean(axis=1)
    df_auc['Mean'] = df_auc.mean(axis=1)

    df_wav['Standard Deviation'] = df_wav.std(axis=1)
    df_pow['Standard Deviation'] = df_pow.std(axis=1)
    df_for['Standard Deviation'] = df_for.std(axis=1)
    df_auc['Standard Deviation'] = df_auc.std(axis=1)

    ##[Writing analysis to excel]##############################################

    print("Writing files")
    writer = pd.ExcelWriter(directory + "analysis{}.xlsx".format(trial_name))
    df_wav.to_excel(writer, "Raw Waveforms")
    df_auc.to_excel(writer, "Area Under the Curve")
    df_for.to_excel(writer, "Fourier Spectra")
    df_pow.to_excel(writer, "Global Power Spectra")
    writer.save()

    ##[Writing means to a single file]#########################################

    #filename = 'C:\\pyscripts\\wavelet_analysis\\Overall_Analysis.xlsx'
    #append_data(filename, df_pow['Mean'].values,  str(trial_name), Yticks)
    ##[Plotting mean power and foruier]########################################
    plt.close('all')
    plt.ioff()
    plt.plot(df_pow['Mean'], df_pow.index.tolist(), label="Global Power")
    plt.plot(df_for['Mean'], df_for.index.tolist(), label="Fourier Power")
    plt.title("Global Power averaged over Time")
    plt.ylabel("Period[cm]")
    plt.xlabel("Power[cm^2]")
    cax = plt.gca()
    #plt.xscale('log')
    cax.set_ylim(np.log2([period.min(), period.max()]))
    cax.set_yticks(np.log2(Yticks))
    cax.set_yticklabels(Yticks)
    plt.legend()
    plt.savefig(directory + '{}_both_{}.png'.format(name, idx), bbox='tight')

    plt.close('all')
    plt.ioff()
    plt.plot(df_pow['Mean'], df_pow.index.tolist(), label="Global Power")
    plt.title("Global Power averaged over Time")
    plt.ylabel("Period[cm]")
    plt.xlabel("Power[cm^2]")
    cax = plt.gca()
    #plt.xscale('log')
    cax.set_ylim(np.log2([period.min(), period.max()]))
    cax.set_yticks(np.log2(Yticks))
    cax.set_yticklabels(Yticks)
    plt.legend()
    plt.savefig(directory + '{}_global_power_{}.png'.format(name, idx),
                bbox='tight')

    plt.close('all')
    plt.ioff()
    plt.plot(df_for['Mean'], df_for.index.tolist(), label="Fourier Power")
    plt.title("Fourier averaged over Time")
    plt.ylabel("Period[cm]")
    plt.xlabel("Power[cm^2]")
    cax = plt.gca()
    #plt.xscale('log')
    cax.set_ylim(np.log2([period.min(), period.max()]))
    cax.set_yticks(np.log2(Yticks))
    cax.set_yticklabels(Yticks)
    plt.legend()
    plt.savefig(directory + '{}_fourier_{}.png'.format(name, idx),
                bbox='tight')

    cap.release()
    return directory
Exemplo n.º 5
0
    def limStructure(self,
                     frequency=100e3,
                     wavelet='Mexican',
                     peaks=False,
                     valleys=False):
        """
        Determination of the time location of the intermittent
        structure accordingly to the method defined in
        *M. Onorato et al Phys. Rev. E 61, 1447 (2000)*

        Parameters
        ----------
        frequency : :obj: `float`
            Fourier frequency considered for the analysis
        wavelet : :obj: `string`
            Mother wavelet for the continuous wavelet analysis
            possibilityes are *Mexican [default]*,  *DOG1* or
            *Morlet*
        peaks : :obj: `Boolean`
            if set it computes the structure only for the peaks
            Default is False
        valleys : :obj: `Boolean`
            if set it computes the structure only for the valleys
            Default is False

        Returns
        -------
        maxima : :obj: `ndarray`
           A binary array equal to 1 at the identification of
           the structure (local maxima)
        allmax : :obj: `ndarray`
            A binary array equal to 1 in all the region where the
            signal is above the threshold

        Attributes
        ----------
        scale : :obj: `float`
            Corresponding scale for the chosen wavelet

        """
        if wavelet == 'Mexican':
            self.mother = wav.MexicanHat()
        elif wavelet == 'DOG1':
            self.mother = wav.DOG(m=1)
        elif wavelet == 'Morlet':
            self.mother = wav.Morlet()
        else:
            print('Not a valid wavelet using Mexican')
            self.mother = wav.Mexican_hat()

        self.freq = frequency
        self.scale = 1. / self.mother.flambda() / self.freq

        # compute the continuous wavelet transform
        wt, sc, freqs, coi, fft, fftfreqs = wav.cwt(self.sig, self.dt, 0.25,
                                                    self.scale, 0, self.mother)
        wt = np.real(np.squeeze(wt))
        wtOr = wt.copy()
        # normalization
        wt = (wt - wt.mean()) / wt.std()
        self.lim = np.squeeze(np.abs(wt**2) / np.mean(wt**2))
        flatness = self.flatness
        newflat = flatness
        threshold = 20.
        while newflat >= 3.05 and threshold > 0:
            threshold -= 0.2
            d_ev = (self.lim > threshold)
            count = np.count_nonzero(d_ev)
            if 0 < count < self.lim.size:
                newflat = np.mean(wt[~d_ev] ** 4) / \
                          np.mean(wt[~d_ev] ** 2) ** 2

        # now we have identified the threshold
        # we need to find the maximum above the treshold
        maxima = np.zeros(self.sig.size)
        allmax = np.zeros(self.sig.size)
        allmax[(self.lim > threshold)] = 1
        imin = 0
        for i in range(maxima.size - 1):
            i += 1
            if self.lim[i] >= threshold > self.lim[i - 1]:
                imin = i
            if self.lim[i] < threshold <= self.lim[i - 1]:
                imax = i - 1
                if imax == imin:
                    d = 0
                else:
                    d = self.lim[imin:imax].argmax()
                maxima[imin + d] = 1

        if peaks:
            ddPeak = ((maxima == 1) & (wtOr > 0))
            maxima[~ddPeak] = 0
        if valleys:
            ddPeak = ((maxima == 1) & (wtOr < 0))
            maxima[~ddPeak] = 0
        return maxima, allmax