Details for Tremor analysis notebook.ipynb

Published by madprime

Description

This notebook helps analyze tremor data via a fast fourier transform, to report the frequency and magnitude of a tremor.

0

Tags & Data Sources

tremor uploaded tremor data

Comments

Please log in to comment.

Notebook
Last updated 4 years, 6 months ago

Tremor analysis notebook

Acquiring data

This notebook expects to analyze a data file from the "Physics Toolbox Sensor Suite" phone app.

How to use this notebook

  • [1] Upload your data file to the Jupyter server
    • Click the "Jupyter" icon in the top left to go to your home directory.
      • (You might want to "open in a new tab"!)
    • Click the "upload" button to upload your data file.
  • [2] Edit the cell below with the following information:
    • target_file: CSV data file name.
  • [3] Run all cells from the top. There are several ways to do run cells, including...
    • On your keyboard, "shift" and "enter" to run each cell (one at a time)
    • Use the "Run" button above (one at a time)
    • Cell → Run all to run everything at once

Load and clean data

Load libraries

Run this to import libraries. They will be used by the code below.

Load data

Clean data

Before doing a fourier transform, data should be a uniform sampling – there should be an equal amount of time between each data timepoint. This isn't always true in the raw data. Use an interpolation to get uniform data.

FFT and plot

/opt/conda/lib/python3.6/site-packages/numpy/core/numeric.py:531: ComplexWarning: Casting complex values to real discards the imaginary part
  return array(a, dtype, copy=False, order=order)
Out[5]:
Text(0, 0.5, 'Magnitude')
Peak frequency: 7.003921174994464 Hz
Peak magnitude: 58.45948546661715

Notebook
Last updated 4 years, 6 months ago

Tremor analysis notebook

Acquiring data

This notebook expects to analyze a data file from the "Physics Toolbox Sensor Suite" phone app.

How to use this notebook

  • [1] Upload your data file to the Jupyter server
    • Click the "Jupyter" icon in the top left to go to your home directory.
      • (You might want to "open in a new tab"!)
    • Click the "upload" button to upload your data file.
  • [2] Edit the cell below with the following information:
    • target_file: CSV data file name.
  • [3] Run all cells from the top. There are several ways to do run cells, including...
    • On your keyboard, "shift" and "enter" to run each cell (one at a time)
    • Use the "Run" button above (one at a time)
    • Cell → Run all to run everything at once
In [1]:
target_file = "sensor-4.csv"

# Edit this to change the plot title. The default uses your file name.
plot_title = "FFT tremor analysis for {}".format(target_file)

Load and clean data

Load libraries

Run this to import libraries. They will be used by the code below.

In [2]:
import math
import statistics

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from scipy.fftpack import fft
from scipy.interpolate import interp1d
import seaborn

Load data

In [3]:
data_raw = pd.read_csv(target_file, parse_dates=['time'])

Clean data

Before doing a fourier transform, data should be a uniform sampling – there should be an equal amount of time between each data timepoint. This isn't always true in the raw data. Use an interpolation to get uniform data.

In [4]:
# Get the median interval time for this data (i.e. typical interval)
intervals = [data_raw.index[i] - data_raw.index[i-1] for
             i in range(1, len(data_raw.index))]
interval = statistics.median(intervals)

# Convert to unix epoch timestamp for easier math.
ts_raw = [t.timestamp() for t in data_raw.time]

# Set up interpolation for total gForce.
gf_raw = list(data_raw.gFTotal)
interpolate = interp1d(ts_raw, gf_raw)

# Create uniform timepoints, derive interpolated gForce values.
ts_uniform = np.linspace(ts_raw[0], ts_raw[-1], len(ts_raw))
avg_delta = (ts_raw[-1] - ts_raw[0]) / len(ts_raw)
gf_uniform = interpolate(ts_uniform)

FFT and plot

In [5]:
gf_fft_all = np.fft.fft(gf_uniform)
freqs_all = np.fft.fftfreq(len(ts_uniform), d=avg_delta)

# discard complex conjugate
target_len = int(len(freqs_all)/2)
freqs = freqs_all[1:target_len]
gf_fft = gf_fft_all[1:target_len]

plt.figure()
plt.plot(freqs, gf_fft)
plt.title(plot_title)
plt.xlabel("Frequency (Hz)")
plt.ylabel("Magnitude")
/opt/conda/lib/python3.6/site-packages/numpy/core/numeric.py:531: ComplexWarning: Casting complex values to real discards the imaginary part
  return array(a, dtype, copy=False, order=order)
Out[5]:
Text(0, 0.5, 'Magnitude')
In [6]:
# Get the maximum value, report the frequency and magintude.
peak_index = np.argmax(gf_fft)
peak_freq = freqs[peak_index]
peak_magnitude = abs(gf_fft[peak_index])

print("Peak frequency: {} Hz".format(peak_freq))
print("Peak magnitude: {}".format(peak_magnitude))
Peak frequency: 7.003921174994464 Hz
Peak magnitude: 58.45948546661715