The purpose of this notebook is to check whether the data collected while the person is being perturbed actually produces different and/or "better" gains than the data collected while the person is not being perturbed.
import sys
sys.path.append('..')
from gaitanalysis.gait import plot_steps
from src import utils
from src.grf_landmark_settings import settings
%matplotlib inline
from IPython.core.pylabtools import figsize
figsize(12, 10)
Load the path to the directory with the experimental data.
trials_dir = utils.trial_data_dir()
Trials data directory is set to /home/moorepants/Data/human-gait/gait-control-identification
Show a table of the currently available trials.
utils.generate_meta_data_table(trials_dir).sort(('nominal-speed', 'subject-id')).head(50)
datetime | id | nominal-speed | notes | subject-id | |
---|---|---|---|---|---|
4 | 2014-05-13 | 79 | 0.8 | This is an unloaded trial (no subject) 10 minu... | 0 |
12 | 2014-02-27 | 34 | 0.8 | This is an unloaded trial (no subject) 10 minu... | 0 |
13 | 2014-03-27 | 52 | 0.8 | This is an unloaded trial (no subject) 10 minu... | 0 |
19 | 2014-03-28 | 58 | 0.8 | This is an unloaded trial (no subject) 10 minu... | 0 |
37 | 2014-04-02 | 64 | 0.8 | This is an unloaded trial (no subject) 10 minu... | 0 |
42 | 2014-03-21 | 43 | 0.8 | This is an unloaded trial (no subject) 10 minu... | 0 |
50 | 2014-02-25 | 30 | 0.8 | This is an unloaded trial (no subject) 10 minu... | 0 |
52 | 2014-05-08 | 70 | 0.8 | This is an unloaded trial (no subject) 10 minu... | 0 |
66 | 2014-02-21 | 22 | 0.8 | This is an unloaded trial (no subject) 10 minu... | 0 |
72 | 2013-12-03 05:06:00 | 1 | NaN | This is a trial that Obinna collected for his ... | 1 |
21 | 2014-03-21 | 46 | 0.8 | This is the trial run for the 10 minute protoc... | 3 |
36 | 2014-02-18 | 12 | 0.8 | This is the trial run for the 10 minute protoc... | 4 |
41 | 2014-02-18 | 12 | 0.8 | This is a trial run for the 10 minute protocol... | 4 |
65 | 2014-02-27 | 32 | 0.8 | This is the trial run for the 10 minute protoc... | 5 |
29 | 2014-03-21 | 40 | 0.8 | This is the trial run for the 10 minute protoc... | 6 |
67 | 2014-02-21 | 16 | 0.8 | This is the trial run for the 10 minute protoc... | 7 |
5 | 2014-02-21 | 19 | 0.8 | This is the trial run for the 10 minute protoc... | 8 |
6 | 2014-02-25 | 25 | 0.8 | This is the trial run for the 10 minute protoc... | 9 |
57 | 2014-04-02 | 61 | 0.8 | This is the trial run for the 10 minute protoc... | 10 |
38 | 2014-02-14 | 9 | 0.8 | This is a trial run for the 10 minute protocol... | 11 |
9 | 2014-03-27 | 49 | 0.8 | This is the trial run for the 10 minute protoc... | 12 |
75 | 2014-03-28 | 55 | 0.8 | This is the trial run for the 10 minute protoc... | 13 |
43 | 2014-05-08 | 67 | 0.8 | This is the trial run for the 10 minute protoc... | 15 |
25 | 2014-05-13 | 76 | 0.8 | This is the trial run for the 10 minute protoc... | 16 |
69 | 2014-05-08 | 73 | 0.8 | This is the trial run for the 10 minute protoc... | 17 |
1 | 2014-05-08 | 71 | 1.2 | This is an unloaded trial (no subject) 10 minu... | 0 |
3 | 2014-03-28 | 59 | 1.2 | This is an unloaded trial (no subject) 10 minu... | 0 |
10 | 2014-03-21 | 44 | 1.2 | This is an unloaded trial (no subject) 10 minu... | 0 |
20 | 2013-10-22 | 3 | 1.2 | This is an unloaded trial (no subject) of the ... | 0 |
32 | 2014-02-25 | 29 | 1.2 | This is an unloaded trial (no subject) 10 minu... | 0 |
33 | 2014-02-27 | 35 | 1.2 | This is an unloaded trial (no subject) 10 minu... | 0 |
35 | 2013-10-22 | 4 | 1.2 | This is an unloaded trial (no subject) of the ... | 0 |
44 | 2013-10-22 | 5 | 1.2 | This is an unloaded trial (no subject) of the ... | 0 |
48 | 2014-05-13 | 80 | 1.2 | This is an unloaded trial (no subject) 10 minu... | 0 |
63 | 2014-04-02 | 65 | 1.2 | This is an unloaded trial (no subject) 10 minu... | 0 |
68 | 2014-03-27 | 53 | 1.2 | This is an unloaded trial (no subject) 10 minu... | 0 |
70 | 2014-02-21 | 23 | 1.2 | This is an unloaded trial (no subject) 10 minu... | 0 |
0 | 2013-10-22 | 8 | 1.2 | This is the first attempt at the 10 minute pro... | 1 |
27 | 2013-10-22 | 6 | 1.2 | This is the first attempt at the 10 minute pro... | 1 |
54 | 2013-10-22 | 7 | 1.2 | This is the first attempt at the 10 minute pro... | 1 |
60 | 2014-03-21 | 47 | 1.2 | This is the trial run for the 10 minute protoc... | 3 |
62 | 2014-02-18 | 13 | 1.2 | This is the trial run for the 10 minute protoc... | 4 |
28 | 2014-02-27 | 31 | 1.2 | This is the trial run for the 10 minute protoc... | 5 |
74 | 2014-03-21 | 41 | 1.2 | This is the trial run for the 10 minute protoc... | 6 |
40 | 2014-02-21 | 17 | 1.2 | This is the trial run for the 10 minute protoc... | 7 |
11 | 2014-02-21 | 20 | 1.2 | This is the trial run for the 10 minute protoc... | 8 |
71 | 2014-02-25 | 26 | 1.2 | This is the trial run for the 10 minute protoc... | 9 |
64 | 2014-04-02 | 62 | 1.2 | This is the trial run for the 10 minute protoc... | 10 |
47 | 2014-02-14 | 10 | 1.2 | This is a trial run for the 10 minute protocol... | 11 |
59 | 2014-03-27 | 50 | 1.2 | This is the trial run for the 10 minute protoc... | 12 |
Trial #68 had nice clean data, so we'll look at that one.
trial_number = '068'
Here I'll extract the data from both the normal walking periods, i.e. the two 1 minute sections at the beginning and end of the trial. Then section out the steps for each and concantenate the steps to give two minutes of data.
event_data_frame, meta_data, event_data_path = \
utils.write_event_data_frame_to_disk(trial_number, event='First Normal Walking')
Trials data directory is set to /home/moorepants/Data/human-gait/gait-control-identification Temporary data directory is set to ../data Loading pre-cleaned data: ../data/cleaned-data-068-first-normal-walking.h5 0.07 s
walking_data, walking_data_path = \
utils.write_inverse_dynamics_to_disk(event_data_frame, meta_data, event_data_path)
Loading pre-computed inverse dynamics from ../data/walking-data-068-first-normal-walking.h5. 0.04 s
params = settings[trial_number]
first_steps, walking_data = utils.section_signals_into_steps(walking_data,
walking_data_path,
filter_frequency=params[0],
threshold=params[1],
num_samples_lower_bound=params[2],
num_samples_upper_bound=params[3])
Loading pre-computed steps from ../data/walking-data-068-first-normal-walking.h5. 0.034455
Now load in the normal walking from the end of the trail.
event_data_frame, meta_data, event_data_path = \
utils.write_event_data_frame_to_disk(trial_number, event='Second Normal Walking')
Trials data directory is set to /home/moorepants/Data/human-gait/gait-control-identification Temporary data directory is set to ../data Loading pre-cleaned data: ../data/cleaned-data-068-second-normal-walking.h5 0.03 s
walking_data, walking_data_path = utils.write_inverse_dynamics_to_disk(event_data_frame, meta_data, event_data_path)
Loading pre-computed inverse dynamics from ../data/walking-data-068-second-normal-walking.h5. 0.03 s
second_steps, walking_data = utils.section_signals_into_steps(walking_data,
walking_data_path,
filter_frequency=params[0],
threshold=params[1],
num_samples_lower_bound=params[2],
num_samples_upper_bound=params[3])
Loading pre-computed steps from ../data/walking-data-068-second-normal-walking.h5. 0.031396
Now concatenate the steps.
from pandas import concat
normal_steps = concat((first_steps, second_steps), ignore_index=True)
And identify a controller.
sensor_labels, control_labels, result, solver = \
utils.find_joint_isolated_controller(normal_steps, event_data_path)
Identifying the controller. Loading pre-computed gains from: ../data/joint-isolated-gain-data-068-second-normal-walking.npz ../data/joint-isolated-gain-data-068-second-normal-walking.h5 0.02 s
fig, axes = utils.plot_joint_isolated_gains_better(sensor_labels, control_labels, result[0], result[3],
normal_steps.mean(axis='items'))
Generating gain plot. 0.66 s
Now let's see what the perturbed walking gives.
event_data_frame, meta_data, event_data_path = utils.write_event_data_frame_to_disk(trial_number)
Trials data directory is set to /home/moorepants/Data/human-gait/gait-control-identification Temporary data directory is set to ../data Loading pre-cleaned data: ../data/cleaned-data-068-longitudinal-perturbation.h5 0.08 s
walking_data, walking_data_path = utils.write_inverse_dynamics_to_disk(event_data_frame, meta_data, event_data_path)
Loading pre-computed inverse dynamics from ../data/walking-data-068-longitudinal-perturbation.h5. 0.07 s
perturbed_steps, walking_data = utils.section_signals_into_steps(walking_data, walking_data_path,
filter_frequency=params[0],
threshold=params[1],
num_samples_lower_bound=params[2],
num_samples_upper_bound=params[3])
Loading pre-computed steps from ../data/walking-data-068-longitudinal-perturbation.h5. 0.109919
Let use the same number of steps that were used in the normal walking.
sensor_labels, control_labels, result, solver = \
utils.find_joint_isolated_controller(perturbed_steps.iloc[:normal_steps.shape[0]], event_data_path)
Identifying the controller. Loading pre-computed gains from: ../data/joint-isolated-gain-data-068-longitudinal-perturbation.npz ../data/joint-isolated-gain-data-068-longitudinal-perturbation.h5 0.02 s
fig, axes = utils.plot_joint_isolated_gains(sensor_labels, control_labels, result[0], result[3])
Generating gain plot. 0.49 s
The difference in the standard deviation of the angles, rates, and torques in the unperturbed gait cycles and the perturbed gait cycles is not that high, especially in the joint angles and rates.
variables = ['FP2.ForY',
'Right.Ankle.PlantarFlexion.Moment',
'Right.Knee.Flexion.Rate',
'Right.Hip.Flexion.Angle']
axes = plot_steps(normal_steps, *variables, mean=False, marker='.')
axes = plot_steps(perturbed_steps, *variables, marker='.')
axes = plot_steps(perturbed_steps, *variables, mean=True)
axes = plot_steps(normal_steps, *variables, axes=axes, mean=True, color='red')
std_normal = normal_steps.std(axis='items')
std_perturbed = perturbed_steps.std(axis='items')
mean_normal = normal_steps.mean(axis='items')
mean_perturbed = perturbed_steps.mean(axis='items')
This should give a relative percent difference in the standard deviation of the perturbed with respect to the unperturbed
(100 * (std_perturbed - std_normal) / mean_normal)[variables]
FP2.ForY | Right.Ankle.PlantarFlexion.Moment | Right.Knee.Flexion.Rate | Right.Hip.Flexion.Angle | |
---|---|---|---|---|
0.00 | -0.702312 | 54.161994 | 7.151136 | 0.640699 |
0.05 | 11.365940 | -16.618172 | 8.692599 | 0.325989 |
0.10 | 4.100349 | 71.255472 | 3.789988 | -0.123368 |
0.15 | 1.676377 | 23.522443 | 15.874787 | -0.845656 |
0.20 | 0.531206 | 17.899615 | -13.288820 | 0.096680 |
0.25 | 1.698780 | 15.616613 | -8.927705 | 2.455398 |
0.30 | -0.259535 | 12.961489 | -11.345291 | 5.930276 |
0.35 | 0.262492 | 10.513914 | -12.782388 | 11.655779 |
0.40 | 1.961494 | 8.256493 | -23.547497 | 27.660178 |
0.45 | 1.948030 | 5.760194 | 72.065400 | -197.805822 |
0.50 | 1.936488 | 3.349429 | 12.771686 | -29.029463 |
0.55 | 6.198706 | 7.167769 | 5.922742 | -20.980507 |
0.60 | 16.974746 | 21.149313 | 4.430004 | -121.752200 |
0.65 | 125.151113 | -1310.678549 | 3.960735 | 17.671251 |
0.70 | -47.947924 | -31.303059 | 15.283454 | 6.389177 |
0.75 | -58.793967 | -132.464771 | -42.495521 | 3.657299 |
0.80 | -18.917167 | -259.085581 | -5.133524 | 2.777270 |
0.85 | -21.892424 | -6606.241418 | -1.386338 | 1.895827 |
0.90 | -14.756297 | 183.709155 | -2.341831 | 1.073166 |
0.95 | -12.233427 | 38.332485 | -5.133980 | 0.226171 |
This is the mean difference in the standard deviations across the gait cycle.
(std_perturbed - std_normal)[variables].mean()
FP2.ForY 12.306176 Right.Ankle.PlantarFlexion.Moment 4.735479 Right.Knee.Flexion.Rate 0.159062 Right.Hip.Flexion.Angle 0.008452 dtype: float64
!git rev-parse HEAD
7ba68f0160c23a61204291ca107ad570ac6f6e5a
!git --git-dir=/home/moorepants/src/GaitAnalysisToolKit/.git --work-tree=/home/moorepants/src/GaitAnalysisToolKit rev-parse HEAD
a3732352747bc03ca839df9ff02ddcbd889e636d
%install_ext http://raw.github.com/jrjohansson/version_information/master/version_information.py
Installed version_information.py. To use it, type: %load_ext version_information
%load_ext version_information
%version_information gaitanalysis, numpy, scipy, pandas, matplotlib, tables, oct2py
Software | Version |
---|---|
Python | 2.7.8 64bit [GCC 4.4.7 20120313 (Red Hat 4.4.7-1)] |
IPython | 2.3.0 |
OS | Linux 3.13.0 37 generic x86_64 with debian jessie sid |
gaitanalysis | 0.1.0dev |
numpy | 1.8.2 |
scipy | 0.14.0 |
pandas | 0.12.0 |
matplotlib | 1.4.0 |
tables | 3.1.1 |
oct2py | 2.4.0 |
Fri Oct 17 11:58:33 2014 EDT |
!pip freeze
DynamicistToolKit==0.3.5 -e git+git@github.com:csu-hmc/GaitAnalysisToolKit.git@a3732352747bc03ca839df9ff02ddcbd889e636d#egg=GaitAnalysisToolKit-origin/HEAD Jinja2==2.7.2 MarkupSafe==0.18 PyYAML==3.11 backports.ssl-match-hostname==3.4.0.2 ipython==2.3.0 matplotlib==1.4.0 numexpr==2.3.1 numpy==1.8.2 oct2py==2.4.0 pandas==0.12.0 patsy==0.3.0 pyparsing==2.0.1 python-dateutil==1.5 pytz==2014.7 pyzmq==14.3.0 scipy==0.14.0 six==1.8.0 statsmodels==0.5.0 tables==3.1.1 tornado==3.2.1 uncertainties==2.4.6.1 wsgiref==0.1.2