示例#1
0
def spectra_2D_map(position_file_names,source_folder_positions=None, modes='xy', navrg=10,
                   frequency_range=None, tag='_Sample_6_Bead_1_', nmax=None,
                   y_axis = '',
                   method = 'fit_ellipse', verbose=False):
    """

    calculated the psds and plots them as a waterfall plot

    Args:
        position_file_names:
        modes:
        navrg:
        y_axis: determines what to use for the y-axis, ['run', 'time (h)', ''] if '' y is equilly spaced
        xlim:
        tag:
        nmax:
        verbose:

    Returns:

    """
    fig, ax = plt.subplots(len(modes), 1, sharex=True, figsize=(18, 5 * len(modes)))

    if len(modes)==1:
        ax = [ax]

    psd_data = {'y_axis':[]}
    for i, filename in enumerate(position_file_names):
        run = int(filename.split(tag)[1].split('-')[0].strip('_'))
        if verbose:
            print(filename, run)
        data, info = load_time_trace(filename, source_folder_positions=source_folder_positions, verbose=False)
        dt = 1./info['info']['FrameRate']
        if verbose:
            print('FrameRate', info['info']['FrameRate'])
        if y_axis == '':
            psd_data['y_axis'].append(i)
        elif y_axis == 'run':
            psd_data['y_axis'].append(run)
        elif y_axis == 'time (h)':
            time = info['info']['File_Modified_Date_Local']
            time = datetime.strptime(time.split('.')[0], '%Y-%m-%d %H:%M:%S')
            if i==0:
                start = time
            time = time-start
            psd_data['y_axis'].append(time.seconds/(60 * 60) + time.days * 24)

        # calculate the psd

        for mode in modes:
            if method == 'fit_ellipse':
                if mode == 'r':
                    x = data['ellipse angle']
                elif mode == 'z':
                    x = data['ellipse a'] * data['ellipse b']
                else:
                    x = data['ellipse ' + mode]
            elif method.lower() == 'bright px':
                x = data['bright px ' + mode]

            x -= np.mean(x)
            if nmax is not None:
                x = x[0:nmax]

            f, p = power_spectral_density(x, time_step=dt, frequency_range=frequency_range)
            p = avrg(p, navrg)

            if mode in psd_data:

                psd_data[mode] = np.vstack([psd_data[mode],p])
            else:
                psd_data[mode] = p


    psd_data['f'] = avrg(f, navrg)


    for a, mode in enumerate(modes):
        z = np.log10(psd_data[mode])  # get data
        y = psd_data['y_axis']
        x = psd_data['f']

        ax[a].pcolormesh(x, y, z)  # plot

        ax[a].set_title(mode + ' data')
        ax[a].set_xlabel('frequency (Hz)')
        ax[a].set_ylabel(y_axis)

    return fig
示例#2
0
def plot_timetrace_energy(x, time_step, window_length =1, start_frame=0, end_frame=None, frequency_range= None, ax = None, verbose = True, velocity_mode=True, return_data=False):
    """

    Args:
        x: position time trace
        time_step:
        window_length: integration window for calculation of the energy should be much larger than typical freq and much smaller than decay time
        start_frame:
        end_frame:
        frequency_range:
        ax:
        verbose:
        velocity_mode: if true return the energy calculated from the velocity psd (units are px^2 Hz^2) if false calculate from position psd (units are px^2)
        return_data:

    Returns:

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

    N_frames = len(x) # total number of frames

    if end_frame is None:
        end_frame = N_frames



    N_windows = (end_frame-start_frame)/window_length # number of windows
    N_windows = int(np.floor(N_windows))

    if verbose:
        print('total number of frames:\t\t{:d}'.format(N_frames))
        print('total number of windows:\t{:d}'.format(N_windows))

    # reshape the timetrace such that each row is a window
    X = x[start_frame:start_frame+window_length*N_windows].reshape(N_windows, window_length)
    P = []
    F = []
    for id, x in enumerate(X):
        f, p = power_spectral_density(x, time_step, frequency_range=frequency_range)
        P.append(p)
        F.append(f[np.argmax(p)])


    df = np.mean(np.diff(f))

    # now calculate the energy (P is in units of px^2/Hz or m^2/Hz)
    if velocity_mode:
        # integrate over velocity psd which is Svv(omega)=Sxx(omega)*omega^2, where Sxx(omega) is the position psd
        # and Svv(omega) the velocity psd
        x = np.sum(P*(2*np.pi*f)**2, axis=1)*df
    else:
        # integrate over position psd Sxx(omega)
        x = np.sum(P, axis=1)*df

    time = np.arange(len(x)) * time_step * window_length
    ax.plot(time, x)
    ax.set_xlabel('time (s)')

    if return_data:
        return fig, ax, (time, x, F)
    else:
        return fig, ax
示例#3
0
def waterfall(position_file_names,source_folder_positions=None, modes='xy', navrg=10, off_set_factor=-3,
              frequency_range=None, tag='_Sample_6_Bead_1_', nmax=None,
              method = 'fit_ellipse', verbose=False):
    """

    calculated the psds and plots them as a waterfall plot

    Args:
        position_file_names:
        modes:
        navrg:
        off_set_factor:
        xlim:
        tag:
        nmax:
        verbose:

    Returns:

    """
    fig, ax = plt.subplots(len(modes), 1, sharex=True, figsize=(18, 5 * len(modes)))

    if len(modes)==1:
        ax = [ax]


    for i, filename in enumerate(position_file_names):
        run = int(filename.split(tag)[1].split('-')[0].strip('_'))
        if verbose:
            print(filename, run)
        data, info = load_time_trace(filename, source_folder_positions=source_folder_positions, verbose=False)
        dt = 1./info['info']['FrameRate']
        # calculate the psd
        psd_data = {}
        for mode in modes:
            if method == 'fit_ellipse':
                if mode == 'r':
                    x = data['ellipse angle']
                elif mode == 'z':
                    x = data['ellipse a'] * data['ellipse b']
                else:
                    x = data['ellipse ' + mode]
            elif method.lower() == 'bright px':
                x = data['bright px ' + mode]

            x -= np.mean(x)
            if nmax is not None:
                x = x[0:nmax]
            f, p = power_spectral_density(x, time_step=dt, frequency_range=frequency_range)
            psd_data[mode] = p
        psd_data['f'] = f

        f = psd_data['f'][1:]  # get rid of first point (DC)
        f = avrg(f, navrg)  # refold (assume that signal is aliasied)
        #         f = np.mean(df_modes['FrameRate'])-avrg(f, navrg)  # refold (assume that signal is aliasied)

        for a, mode in enumerate(modes):
            d = psd_data[mode]  # get data
            d = avrg(d[1:] * 10 ** (off_set_factor * i), navrg)  # shift on a log scale to get the waterfall effect
            ax[a].semilogy(f, d, label=str(run), alpha=0.5)  # plot




    # if xlim is not None:
    #     assert len(xlim) == 2
    #     ax[0].set_xlim(xlim)
    for a, mode in enumerate(modes):
        ax[a].set_title(mode + ' data')
    ax[a].set_xlabel('frequency (Hz)')
    plt.legend(loc=(1, 0.0))

    return fig
示例#4
0
def plot_psds(x, time_step, window_ids = None, start_frame = 0, window_length= 1000, end_frame = None,full_spectrum = True, frequency_range= None, ax = None,  plot_avrg = False, return_data=False):
    """

    time trace x is chopped up into segments of length window_length

    for each window we calculate the psd

    Plots all the PSD calculated from the timetrace as a 1D plot
    Args:
        x: time trace
        time_step: time_step between datapoints
        window_ids: the id of the window to be plotted if None, calculate the spectrum from the entire timetrace
        start_frame: starting frame for analysis (default 0)
        window_length: length of window over which we compute the psd (default 1000)
        end_frame: end frame for analysis (optional if None end_frame is len of total timetrace)
        full_spectrum: if true show full spectrum if false just mark the frequency range
        frequency_range: a tupple or list of two elements frange =[mode_f_min, mode_f_min] that marks a freq range on the plot if full_spectrum is False otherwise plot only the spectrum within the frequency_range
        plot_avrg: if true plot the time averaged PSD, windows ids should be None
    Returns:

    """

    if plot_avrg:
        assert window_ids is None

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

    if window_ids is None:
        if full_spectrum:
            f, p = power_spectral_density(x, time_step, frequency_range=None)
        else:
            f, p = power_spectral_density(x, time_step, frequency_range=frequency_range)
        ylim = [min(p), max(p)]
    else:

        N_frames = len(x) # total number of frames

        if end_frame is None:
            end_frame = N_frames


        N_windows = (end_frame-start_frame)/window_length # number of windows
        N_windows = int(np.floor(N_windows))

        print('total number of frames:\t\t{:d}'.format(N_frames))
        print('total number of windows:\t{:d}'.format(N_windows))

        # reshape the timetrace such that each row is a window
        X = x[start_frame:start_frame+window_length*N_windows].reshape(N_windows, window_length)
        P = []
        if plot_avrg:

            for x in X:
                if full_spectrum:
                    f, p = power_spectral_density(x, time_step, frequency_range=None)
                else:
                    f, p = power_spectral_density(x, time_step, frequency_range=frequency_range)
                P.append(p)


            pmean = np.mean(P, axis=0)
            ax.semilogy(f, pmean)
            ax.set_ylim([min(pmean), max(pmean)])
        else:
            for id, x in enumerate(X):

                if id in window_ids:

                    if full_spectrum:
                        f, p = power_spectral_density(x, time_step, frequency_range=None)
                    else:
                        f, p = power_spectral_density(x, time_step, frequency_range=frequency_range)
                    P.append(p)
                    ylim = [np.min(P), np.max(P)]



    xlim = [min(f), max(f)]


    if window_ids is None:
        ax.semilogy(f, p, '-')
    else:
        for p, id in zip(P, window_ids):
            ax.semilogy(f, p, '-', label=id)
        plt.legend(loc=(1, 0))

    if not frequency_range is None:
        [mode_f_min, mode_f_max] = frequency_range
        ax.plot([mode_f_min, mode_f_min], ylim, 'k--')
        ax.plot([mode_f_max, mode_f_max], ylim, 'k--')
    ax.set_xlim(xlim)
    ax.set_ylim(ylim)
    ax.set_xlabel('frequency (Hz)')
    ax.set_ylabel('psd (arb.u.)')

    if return_data:
        return fig, ax, {'spectra': P, 'frequencies': f}
    else:
        return fig, ax
示例#5
0
def plot_psd_vs_time(x, time_step, start_frame=0, window_length=1000, end_frame=None, full_spectrum=True,
                     frequency_range=None, ax=None, plot_avrg=False, verbose=False, return_data=False, plot_hist=False):
    """

    Args:
        x: time trace
        time_step: time_step between datapoints
        start_frame: starting frame for analysis (default 0)
        window_length: length of window over which we compute the psd (default 1000)
        end_frame: end frame for analysis (optional if None end_frame is len of total timetrace)
        full_spectrum: if true show full spectrum if false just mark the frequency range
        frequency_range: a tupple or list of two elements frange =[mode_f_min, mode_f_min] that marks a freq range on the plot if full_spectrum is False otherwise plot only the spectrum within the frequency_range
        plot_avrg: if true plot the time averaged PSD on top of the 2D plot
        plot_hist: if true plot the hisogram of the max freq per window on top of the 2Dplot

    Returns:

    """

    N_frames = len(x) # total number of frames

    if end_frame is None:
        end_frame = N_frames


    N_windows = (end_frame-start_frame)/window_length # number of time
    N_windows = int(np.floor(N_windows))

    if verbose:
        print('total number of frames:\t\t{:d}'.format(N_frames))
        print('total number of windows:\t{:d}'.format(N_windows))

    # substract mean to get rid of large 0-frequency peak
    x = x-np.mean(x)
    # reshape the timetrace such that each row is a window
    if isinstance(x, np.ndarray):
        # numpy
        X = x[start_frame:start_frame+window_length*N_windows].reshape(N_windows, window_length)
    else:
        # pandas
        X = x[start_frame:start_frame + window_length * N_windows].values.reshape(N_windows, window_length)
    P = []
    # c = 0
    for x in X:
        # c+=1
        if full_spectrum:
            f, p = power_spectral_density(x, time_step, frequency_range=None)
        else:
            f, p = power_spectral_density(x, time_step, frequency_range=frequency_range)
        P.append(p)
        # print(c,len(p), np.min(p))




    time = np.arange(N_windows) * time_step * window_length

    xlim = [min(f), max(f)]
    ylim = [min(time), max(time)]

    if ax is None:
        if plot_avrg:
            fig, ax = plt.subplots(2, 1, sharex=True)
            ax_id = 1
        elif plot_hist:
            fig, ax = plt.subplots(1, 2)
            ax_id = 0
        else:
            fig, ax = plt.subplots(1, 1)
            ax =[ax]
            ax_id = 0

    if plot_hist:
        ax[ax_id].pcolormesh(f, time, P)
    else:
        ax[ax_id].pcolormesh(f, time, np.log(P))


    # print(np.min(P, axis=1), len(np.min(P, axis=1)))

    if not frequency_range is None:
        [mode_f_min, mode_f_max] = frequency_range
        ax[ax_id].plot([mode_f_min, mode_f_min], ylim, 'k--')
        ax[ax_id].plot([mode_f_max, mode_f_max], ylim, 'k--')



    if plot_avrg:
        pmean = np.mean(P, axis=0)
        ax[0].semilogy(f, pmean)
        ax[0].set_ylim([min(pmean), max(pmean)])
        ax[ax_id].set_ylim([min(pmean), max(pmean)])


    elif plot_hist:
        fmax = f[np.argmax(P, axis=1)]
        ax[1].hist(fmax)
        # ax[0].set_ylim([min(pmean), max(pmean)])
        # ax[ax_id].set_ylim([min(pmean), max(pmean)])


    ax[ax_id].set_xlim(xlim)
    ax[ax_id].set_ylim(ylim)
    ax[ax_id].set_xlabel('frequency (Hz)')
    ax[ax_id].set_ylabel('time (s)')

    if return_data:
        return fig, ax, {'spectra': P, 'frequencies': f}
    else:
        return fig, ax
示例#6
0
def plot_ellipse_spectra(data, info, annotation_dict={}, freq_range=None, n_avrg=None, plot_type = 'lin', verbose=False, normalize=True, return_data=False, axes = None):
    """

    Args:
        data:
        info:
        annotation_dict:
        freq_range:
        n_avrg: average n_avrg successive datapoint to smoothen the data
        plot_type:

    Returns:

    """

    coordinates = [['x', 'y', 'area'], ['a', 'b', 'angle']]
    feature = 'ellipse'

    time_step = 1. / info['info']['FrameRate']
    axes_shape = np.shape(coordinates)

    if axes is None:
        fig, axes = plt.subplots(axes_shape[0], axes_shape[1], sharey=False, sharex=False,
                                 figsize=(8 * axes_shape[1], 3 * axes_shape[0]))
    else:
        fig = None




    if return_data:
        #containers for the data
        p_list = []
    modes = {}
    for i, row in enumerate(zip(coordinates, axes)):

        #     print('row', row)
        c_row, a_row = row
        for c, ax in zip(c_row, a_row):

            if verbose:
                print('plotting ' + c)

            if c == 'area':
                d = data[feature + ' a'] * data[feature + ' b'] * np.pi
            else:
                d = data[feature + ' ' + c]

            d = d - np.mean(d) # get rid of DC off set

            f, p = power_spectral_density(d, time_step, frequency_range=freq_range)

            if n_avrg is not None:
                f, p = avrg(f, n=n_avrg), avrg(p, n=n_avrg)

            if normalize:
                p = p / max(p)

            if plot_type == 'log':
                ax.loglog(f, p, linewidth=3)
            elif plot_type == 'lin':
                ax.plot(f, p, linewidth=3)
            elif plot_type == 'semilogy':
                ax.semilogy(f, p, linewidth=3)
            elif plot_type == 'semilogx':
                ax.semilogx(f, p, linewidth=3)

            # if we plot on a preexisting plot, don't add labels
            if fig is not None:
                if len(annotation_dict) > 0:
                    annotate_frequencies(ax, annotation_dict, higher_harm=1)
                #         annotate_frequencies(ax, annotation_dict, higher_harm=1)

            modes[c] = f[np.argmax(p)]

            ax.set_ylabel(c + ' (norm)')
            ax.set_xlim((min(f), max(f)))

            if i == len(coordinates) - 1:
                ax.set_xlabel('frequency (Hz)')

            if return_data:

                # containers for the data
                p_list.append(p)

    if return_data:
        return fig, axes, {'frequencies': f, 'spectra':p_list, 'coordinates':coordinates}
    else:
        return fig, axes
示例#7
0
def plot_ellipse_spectra_zoom(data, info, annotation_dict={}, freq_window=1, n_avrg=None, plot_type='lin', normalize=True, axes=None, verbose=False):
    for mode in ['x', 'y', 'z', '2r', 'r', 'm']:
        assert mode in annotation_dict

    if normalize is True:
        normalize = 'max_peak'
    elif normalize is False:
        normalize = 'false'

    assert normalize in ['max_peak', 'false', 'std_dev']

    coordinates = [['x', 'y', 'z'], ['r', '2r', 'm']]
    feature = 'ellipse'

    time_step = 1. / info['info']['FrameRate']
    axes_shape = np.shape(coordinates)


    if axes is None:
        fig, axes = plt.subplots(axes_shape[0], axes_shape[1], sharey=False, sharex=False,
                                 figsize=(8 * axes_shape[1], 3 * axes_shape[0]))
    else:
        fig = None

    if verbose:
        print('axes shape', axes_shape, np.shape(axes), np.shape(coordinates))

    modes = {}
    for i, row in enumerate(zip(coordinates, axes)):

        c_row, a_row = row
        if verbose:
            print('row', i, c_row)
        if verbose:
            print('columns', np.shape(c_row), np.shape(a_row))
        for mode, ax in zip(c_row, a_row):
            if verbose:
                print('====', mode)
            axis_peak = mode
            # if mode in ['x', 'y', 'z']:
            #     data_labels = ['x', 'y', 'area']
            # elif mode in ['r', '2r', 'm']:
            #     data_labels = ['area', 'angle']

            if mode in ['x', 'y']:
                data_labels = [mode]
            elif mode in ['r', '2r', 'm', 'z']:
                data_labels = ['area']

            for data_label in data_labels:

                # as a proxy for the z mode we use the area
                if data_label == 'area':
                    d = data[feature + ' a'] * data[feature + ' b'] * np.pi
                else:
                    d = data[feature + ' ' + data_label]

                d = d - np.mean(d)  # get rid of DC off set


                if normalize == 'std_dev':
                    d /= np.std(d)

                # set the frequency range to be +- freq_window/2 around the peak
                frequency_range = (max(0, annotation_dict[axis_peak][0] - 0.5 * freq_window),
                                   min(annotation_dict[axis_peak][0] + 0.5 * freq_window, 0.5 * info['info']['FrameRate']))

                f, p = power_spectral_density(d, time_step, frequency_range=frequency_range)

                if n_avrg is not None:
                    f, p = avrg(f, n=n_avrg), avrg(p, n=n_avrg)

                if normalize == 'max_peak':
                    p = p / max(p)

                if plot_type == 'log':
                    ax.loglog(f, p, linewidth=3)
                elif plot_type == 'lin':
                    ax.plot(f, p, linewidth=3)
                elif plot_type == 'semilogy':
                    ax.semilogy(f, p, linewidth=3)
                elif plot_type == 'semilogx':
                    ax.semilogx(f, p, linewidth=3)

            # line_length = 0.2
            # # trying to get better lengths for log plots but doesn't work...
            # # if plot_type in ['lin', 'semilogx']:
            # #     line_length = 0.2
            # #
            # # elif plot_type in ['log', 'semilogy']:
            # #     line_length = 1-0.8*min(p / max(p))
            #
            # if len(annotation_dict) > 0:
            #     annotate_frequencies(ax, annotation_dict, x_off=0.1*freq_window, line_length=line_length, higher_harm=1)
            # #         annotate_frequencies(ax, annotation_dict, higher_harm=1)

            modes[mode] = f[np.argmax(p)]
            if normalize == 'max_peak':
                ax.set_ylabel(mode + ' (norm max peak)')
            elif normalize == 'std_dev':
                ax.set_ylabel(mode + ' (norm std)')
            else:
                ax.set_ylabel(mode)
            ax.set_xlim((min(f), max(f)))

            if i == len(coordinates) - 1:
                ax.set_xlabel('frequency (Hz)')

    return fig, axes
示例#8
0
    position_file_names = get_position_file_names(source_folder_positions,
                                                  method=method,
                                                  runs=runs)
modes = 'xy'
psd_data = {m: None for m in modes}
for filename in position_file_names:
    print(filename)
    data, info = load_time_trace(
        filename,
        source_folder_positions=source_folder_positions,
        verbose=False)
    dt = 1. / info['info']['FrameRate']
    for mode in modes:
        x = data[method.lower().split('_')[-1] + ' ' + mode]
        x -= np.mean(x)
        f, p = power_spectral_density(x, time_step=dt)
        psd_data[mode] = p
    psd_data['f'] = f

    df_peaks = find_peaks_in_psd(
        psd_data,
        fmin=fmin,
        fmax=fmax,
        nbin=nbin,
        max_number_of_peaks=max_number_of_peaks,
        height_threshold_factor=height_threshold_factor,
        distance=distance)

    folder = os.path.join(os.path.dirname(source_folder_positions[:-1]),
                          'peak_data')
    if not os.path.exists(folder):