Quickstart

The best way to get started using Tweezepy is to use it for a project. Here’s an annotated fully-functional example that demonstrates standard usage.

For new Python users, this example is carried out in a Jupyter notebook. If you have Jupyter installed, you can download and run the notebook locally (using the download option in the header above) or run it online using Binder (also in the header above).

Load in data

Standard usage of Tweezepy takes in a 1D array of bead positions in nm, trace, collected at a known sampling frequency, fsample. There are many ways to load data into Python depending on its format. Here is a quick tutorial for how to load in data from csv files.

For this tutorial, we will use an example trajectory that is included with Tweezepy. The sampling frequency for this data was 400 Hz.

import numpy as np # Loads the numpy package
import matplotlib.pyplot as plt # Loads the matplotlib package for plotting
from tweezepy import load_trajectory # Loads in the exampled trajectory in tweezepy
fsample = 400 # sampling frequency in Hz
trace = load_trajectory() # load in trajectory in nm
N = len(trace) # number of points in trajectory
time = np.arange(N)/fsample # time in s
fig,ax = plt.subplots(figsize=(8,3), # Figure size
                      ncols=2, # number of columns in figure
                      gridspec_kw={'width_ratios':[3,1], # width ratio of columns
                                   'wspace':0}) # space between columns
ax[0].plot(time, trace) # Plot bead positions as a function of time
ax[1].hist(trace, bins=100, orientation = 'horizontal') # Plot histogram of bead positions
ax[0].set_xlabel('Time (s)') # Label x axis
ax[0].set_ylabel('Bead position (nm)') # Label yaxis
ax[1].set_xticks([]) # Remove xticks on histogram axis
ax[1].set_yticks([]); # Remove yticks on historgram axis
../../_images/quickstart_4_0.png

The plot above shows the bead positions at each time point in the example trajectory and a histogram of the bead positions.

Using the power spectral density (PSD) method

The power spectral density (PSD) method is used via the PSD class. Use Python’s built-in help function to see the class’s docstring, including all its expected inputs (parameters) and available methods. To do so, type the following:

help(PSD)

Estimating the PSD of a trajectory

To estimate the PSD of a trajectory, input the trajectory (in nm) and sampling frequency (in Hz) into the PSD class. By default, it uses Welch’s method, splitting the trajectory into three half-overlapping bins, calculating the PSD values for each bin, and averaging them together to reduce noise. The resulting PSD values are stored in a dictionary that can be directly accessed via the data attribute.

from tweezepy import PSD # Load in PSD class
psd = PSD(trace,fsample) # Estimate PSD values
for key, value in psd.data.items():
    print(key, ' : ', value)
x  :  [7.81250000e-03 1.56250000e-02 2.34375000e-02 ... 1.99976562e+02
 1.99984375e+02 1.99992188e+02]
shape  :  [3. 3. 3. ... 3. 3. 3.]
y  :  [2.36022201e+02 3.37331831e+02 2.30037921e+02 ... 2.84133014e-01
 5.72460759e-01 8.58512762e-01]
yerr  :  [1.36267481e+02 1.94758624e+02 1.32812456e+02 ... 1.64044272e-01
 3.30510373e-01 4.95662574e-01]

Fitting a model to the estimated PSD using maximum likelihood estimation (MLE)

To fit a model to the estimated PSD and estimate parameters, use the mlefit method in the PSD class. By default, it uses the analytical function from Eq. 7 in Morgan and Saleh (2021) and Lansdorp and Saleh (2012) which assumes zero dead-time and accounts for aliasing and motion blur. As with the data, the resulting parameters and their associated uncertainties are stored in a dictionary, which can be accessed directly through the results attribute.

psd.mlefit() # Perform MLE fit on data
for key, value in psd.results.items():
    print(key, ' : ', value)
chi2  :  208597.91145770502
redchi2  :  8.1493109136893
g  :  1.0010433861570223e-05
g_error  :  5.533212958186353e-08
k  :  0.0006333567283668794
k_error  :  8.130228755790806e-06
support  :  1.0
p-value  :  0.0
AIC  :  89948.62650857156
AICc  :  89948.62697739482

The PSD values and MLE fit can also be plotted via the built-in plotting method.

fig,ax = psd.plot(data_label='data',fit_label = 'MLE fit') # Plot PSD values and MLE fit
ax[0].legend() # Add legend to upper axis
../../_images/quickstart_12_0.png

Lastly, when using the PSD class there is an optional bins parameter, which determines the number of half-overlapping bins to use. More bins reduces noise at the cost of low frequency resolution. For example, here is the estimated PSD values using 5, 15, or 25 half-overlapping bins.

bins = [5,15,25] # number of half-overlapping bins
fig = plt.figure() # figure setup
for b in bins:
    psd = PSD(trace,fsample = fsample,  bins=b) # estimate PSD values
    fig, ax = psd.plot(fig=fig,data_label=b) # plot PSD values
ax[0].legend(title = '# of bins') # add legend to axis
../../_images/quickstart_14_0.png

Using the Allan variance (AV) method

The Allan Variance (AV) method is used via the AV class. You can use the built-in help() function to print the class’s docstring, which includes a description of all its inputs (parameters) and methods. To do so, type the following:

help(AV)

Estimating the AV of a trajectory

To estimate AV values, input the trajectory (in nm) and sampling frequency (in Hz) into the AV class. The estimated AV values are stored in a dictionary that can be accessed via the data attribute. By default, the AV class uses the overlapping AV, octave spaced samples, and calculates the type of noise and equivalent degrees of freedom. Because the AV method uses logarithmically spaced bins, there is no optional bins parameter, somewhat simplifying its use for force calibration.

from tweezepy import AV # Load in AV class
av = AV(trace,fsample) # Estimate AV values
for key, value in av.data.items():
    print(key, ' : ', value)
x  :  [2.500e-03 5.000e-03 1.000e-02 2.000e-02 4.000e-02 8.000e-02 1.600e-01
 3.200e-01 6.400e-01 1.280e+00 2.560e+00 5.120e+00 1.024e+01 2.048e+01
 4.096e+01]
shape  :  [3.90583820e+04 2.19038208e+04 1.12664407e+04 5.67381938e+03
 2.14800855e+03 1.06986415e+03 5.32777801e+02 2.66111158e+02
 1.32777871e+02 6.61112985e+01 3.27781570e+01 1.61118881e+01
 7.77941176e+00 3.78125000e+00 1.78571429e+00]
y  :  [ 607.28884303 1081.44344278 1725.8873072  2295.80653154 2362.37579231
 1791.55502062 1134.34404209  657.39308939  354.5921528   158.06307178
   62.49896924   29.20585681   15.19484232   10.18525082    5.95160116]
yerr  :  [ 3.07282748  7.30708017 16.25994484 30.47877682 50.97191858 54.77291233
 49.14413936 40.29893717 30.77274727 19.43983499 10.91642887  7.27606773
  5.44782086  5.23786176  4.45377049]

Fitting a model to the estimated AV using maximum likelihood estimation (MLE)

To fit a model to the estimated AV values, use the mlefit method of the AV class. By default, it performs MLE using the analytical function from Eq. 9 in Morgan and Saleh (2021) or Eq. 17 in Lansdorp and Saleh (2012). After fitting, the parameters and their associated uncertainties can be accessed directly from the results attribute.

av.mlefit() # Perform MLE fit on AV data
for key, value in av.results.items():
    print(key, ' : ', value)
chi2  :  14.346818631382492
redchi2  :  1.1036014331832686
g  :  1.0041155314204818e-05
g_error  :  6.688028898070111e-08
k  :  0.0006360035178028457
k_error  :  7.325143945228793e-06
support  :  0.999911671324171
p-value  :  3.1085352224861228e-61
AIC  :  126.52377592444978
AICc  :  127.52377592444978

We can also plot the AV values and MLE fit using the built-in plotting method.

fig,ax = av.plot(data_label='data',fit_label = 'MLE fit')  # Plot AV values and MLE fit
ax[0].legend() # Add legend to upper axis
plt.show()
../../_images/quickstart_21_0.png

Finally, the AV class has a few extra optional parameters. These should not be used for MLE fitting or calibration, but they may be useful in visualizing some types of parasitic noise. For example, in addition to octave sampling, the AV values can be estimated and plotted for all observation times and decade spaced observation times. Note that calculating AV values for all observation times can be slow.

fig = plt.figure()
for taus in ['octave','decade']:
    av = AV(trace,fsample=fsample,taus=taus)
    fig,ax = av.plot(fig=fig,data_label=taus)
ax[0].legend(title='taus')
fig = plt.figure()
av = AV(trace,fsample=fsample,taus='all')
fig,ax = av.plot(fig=fig, data_label = 'all')
ax[0].legend(title='taus')
<matplotlib.legend.Legend at 0x231f1ddd820>
../../_images/quickstart_23_1.png ../../_images/quickstart_23_2.png