extractors.pyGait¶
Module: extractors.pyGait
¶
This program implements some of the feature extraction equations from:
“iGAIT: An interactive accelerometer based gait analysis system” Mingjing Yang, Huiru Zheng, Haiying Wang, Sally McClean, Dave Newell. 2012. Computer methods and programs in biomedicine 108:715723. DOI:10.1016/j.cmpb.2012.04.004 http://www.ncbi.nlm.nih.gov/pubmed/22575802
iGait was written as a Matlab file and compiled as a Windows application. It assumes a fixed accelerometer position, and derived heel strike timings from an assumed anteriorposterior orientation along the yaxis.
 iGAIT inputs ::
 sample rate
 threshold (anteriorposterior acceleration, to detect heel contact)
 distance
 iGAIT features ::
 spatiotemporal features, from estimates of heel strikes:
 cadence = number of steps divided by walking time
 distancebased measures (mean step length, velocity)
 regularity and symmetry (each direction):
 step/stride regularity
 symmetry
root mean square (each direction)
 spectral features (each direction):
 integral of the power spectral density (IPSD)
 main frequency: frequency with the maximum value of PSD
 frequencies when PSD is cumulated (CPSD)
 pyGait functions compute all of iGAIT’s features except spectral features::
 gait_features() for all heel strikebased estimates:
 cadence
 mean step length and velocity (if distance supplied)
 regularity and symmetry (each direction)
 root_mean_square():
 root mean square (each direction)
 Authors:
 Arno Klein, 2015 (arno@sagebase.org) http://binarybottle.com
 Elias ChaibubNeto, 2015 (neto@sagebase.org)
Copyright 2015, Sage Bionetworks (http://sagebase.org), Apache v2.0 License
Functions¶

mhealthx.extractors.pyGait.
gait
(strikes, data, duration, distance=None)¶ Extract gait features from estimated heel strikes and accelerometer data.
This function extracts all of iGAIT’s features that depend on the estimate of heel strikes:
 cadence = number of steps divided by walk time  step/stride regularity  step/stride symmetry  mean step/stride length and velocity (if distance supplied)
 strikes : numpy array
 heel strike timings
 data : list or numpy array
 accelerometer data along forward axis
 duration : float
 duration of accelerometer reading (s)
 distance : float
 distance traversed
 number_of_steps : integer
 estimated number of steps based on heel strikes
 velocity : float
 velocity (if distance)
 avg_step_length : float
 average step length (if distance)
 avg_stride_length : float
 average stride length (if distance)
 cadence : float
 number of steps divided by duration
 step_durations : numpy array
 step durations
 avg_step_duration : float
 average step duration
 sd_step_durations : float
 standard deviation of step durations
 strides : list of two lists of floats
 stride timings for each side
 avg_number_of_strides : float
 estimated number of strides based on alternating heel strikes
 stride_durations : list of two lists of floats
 estimated stride durations
 avg_stride_duration : float
 average stride duration
 sd_step_durations : float
 standard deviation of stride durations
 step_regularity : float
 measure of step regularity along axis
 stride_regularity : float
 measure of stride regularity along axis
 symmetry : float
 measure of gait symmetry along axis
>>> from mhealthx.xio import read_accel_json, compute_sample_rate >>> input_file = '/Users/arno/DriveWork/mhealthx/mpower_sample_data/deviceMotion_walking_outbound.json.itemsa2ab93336d634676977a08591a5d837f5221783798792869048.tmp' >>> device_motion = True >>> start = 150 >>> t, axyz, gxyz, uxyz, rxyz, sample_rate, duration = read_accel_json(input_file, start, device_motion) >>> ax, ay, az = axyz >>> from mhealthx.extractors.pyGait import heel_strikes >>> threshold = 0.2 >>> order = 4 >>> cutoff = 5 >>> data = ay >>> plot_test = False >>> strikes, strike_indices = heel_strikes(data, sample_rate, threshold, order, cutoff, plot_test) >>> from mhealthx.extractors.pyGait import gait >>> distance = 90 >>> a = gait(strikes, data, duration, distance)

mhealthx.extractors.pyGait.
gait_regularity_symmetry
(data, step_period, stride_period)¶ Compute step and stride regularity and symmetry from accelerometer data.
The iGAIT software assumes that the yaxis is anteriorposterior, and restricts some feature extraction to this orientation. In this program, we compute every measure for an arbitrary axis.
From Yang, et al., 2012:
“The peak value a1 = NFC(t1), which is found at the t1 lag time to be a step period, indicates the step regularity in a direction. The peak value a2 = NFC(t2), which was found at the t2 lag time to be a stride period, indicates the stride regularity in a direction. The variance of the stride regularity and step regularity D = a2  a1, can be used as an indicator to measure gait asymmetry. A smaller value of D indicates a more symmetric gait. A larger value of D indicates a more asymmetric gait. In total, iGAIT extracts seven regularity and symmetry features from the acceleration data, namely
 Step regularity: vertical (VT), anteriorposterior (AP) directions  Stride regularity: VT, AP, mediallateral (ML) directions  Symmetry: VT, AP directions
 data : list or numpy array
 accelerometer data for one (preferably forward) axis
 step_period : integer
 step period
 stride_period : integer
 stride period
 step_regularity : float
 step regularity measure along axis
 stride_regularity : float
 stride regularity measure along axis
 symmetry : float
 symmetry measure along axis
>>> from mhealthx.xio import read_accel_json >>> from mhealthx.extractors.pyGait import gait_regularity_symmetry >>> input_file = '/Users/arno/DriveWork/mhealthx/mpower_sample_data/deviceMotion_walking_outbound.json.itemsa2ab93336d634676977a08591a5d837f5221783798792869048.tmp' >>> device_motion = True >>> start = 150 >>> t, axyz, gxyz, uxyz, rxyz, sample_rate, duration = read_accel_json(input_file, start, device_motion) >>> ax, ay, az = axyz >>> data = ay >>> step_period = 2 >>> stride_period = 1 >>> step_regularity, stride_regularity, symmetry = gait_regularity_symmetry(data, step_period, stride_period)

mhealthx.extractors.pyGait.
heel_strikes
(data, sample_rate, threshold=0.2, order=4, cutoff=5, plot_test=False, t=None)¶ Estimate heel strike times between sign changes in accelerometer data.
The iGAIT software assumes that the yaxis is anteriorposterior, and restricts some feature extraction to this orientation. In this program, we compute heel strikes for an arbitrary axis.
Re: heel strikes (from Yang, et al., 2012): “The heel contacts are detected by peaks preceding the sign change of AP acceleration [3]. In order to automatically detect a heel contact event, firstly, the AP acceleration is low pass filtered by the 4th order zero lag Butterworth filter whose cut frequency is set to 5 Hz. After that, transitional positions where AP acceleration changes from positive to negative can be identified. Finally the peaks of AP acceleration preceding the transitional positions, and greater than the product of a threshold and the maximum value of the AP acceleration are denoted as heel contact events... This threshold is defined as the ratio to the maximum value of the AP acceleration, for example 0.5 indicates the threshold is set at 50% of the maximum AP acceleration. Its default value is set to 0.4 as determined experimentally in this paper, where this value allowed correct detection of all gait events in control subjects. However, when a more irregular pattern is analysed, the threshold should be less than 0.4. The user can test different threshold values and find the best one according to the gait event detection results.”
 data : list or numpy array
 accelerometer data along one axis (preferably forward direction)
 sample_rate : float
 sample rate of accelerometer reading (Hz)
 threshold : float
 ratio to the maximum value of the anteriorposterior acceleration
 order : integer
 order of the Butterworth filter
 cutoff : integer
 cutoff frequency of the Butterworth filter (Hz)
 plot_test : Boolean
 plot heel strikes?
 t : list or numpy array
 accelerometer time points
 strikes : numpy array of floats
 heel strike timings
 strike_indices : list of integers
 heel strike timing indices
>>> from mhealthx.xio import read_accel_json >>> from mhealthx.signals import compute_sample_rate >>> input_file = '/Users/arno/DriveWork/mhealthx/mpower_sample_data/deviceMotion_walking_outbound.json.itemsa2ab93336d634676977a08591a5d837f5221783798792869048.tmp' >>> device_motion = True >>> start = 150 >>> t, axyz, gxyz, uxyz, rxyz, sample_rate, duration = read_accel_json(input_file, start, device_motion) >>> ax, ay, az = axyz >>> from mhealthx.extractors.pyGait import heel_strikes >>> threshold = 0.4 >>> order = 4 >>> cutoff = max([1, sample_rate/10]) >>> plot_test = True >>> data = np.abs(ax) + np.abs(ay) + np.abs(az) >>> strikes, strike_indices = heel_strikes(data, sample_rate, threshold, order, cutoff, plot_test, t)

mhealthx.extractors.pyGait.
project_axes
(vectors, unit_vectors)¶ Project vectors on unit vectors.
vectors : list of lists of x, y, z coordinates or numpy array equivalent unit_vectors : list of lists of x, y, z coordinates (or numpy arrays)
unit vectors to project vectors onto projection_vectors : list of lists of x, y, z coordinates
 vectors projected onto unit vectors
>>> from mhealthx.xio import read_accel_json >>> from mhealthx.signals import compute_sample_rate >>> input_file = '/Users/arno/DriveWork/mhealthx/mpower_sample_data/deviceMotion_walking_outbound.json.itemsa2ab93336d634676977a08591a5d837f5221783798792869048.tmp' >>> device_motion = True >>> start = 150 >>> t, axyz, gxyz, uxyz, rxyz, sample_rate, duration = read_accel_json(input_file, start, device_motion) >>> vectors = zip(axyz[0], axyz[1], axyz[2]) >>> vectors = [vectors[0], vectors[1], vectors[2]] >>> from mhealthx.extractors.pyGait import project_axes >>> unit_vectors = [1, 1, 1] >>> projection_vectors = project_axes(vectors, unit_vectors)

mhealthx.extractors.pyGait.
project_walk_direction_attitude
(ax, ay, az, uw, ux, uy, uz)¶ Project accelerometer data on local walk direction by attitude rotation.
 ax : list or numpy array
 xaxis accelerometer data
 ay : list or numpy array
 yaxis accelerometer data
 az : list or numpy array
 zaxis accelerometer data
 uw : list or numpy array
 w of attitude quaternion
 ux : list or numpy array
 x of attitude quaternion
 uy : list or numpy array
 y of attitude quaternion
 uz : list or numpy array
 z of attitude quaternion
 px : numpy array
 accelerometer data along x axis projected on unit vector
 py : numpy array
 accelerometer data along y axis projected on unit vector
 pz : numpy array
 accelerometer data along z axis projected on unit vector
>>> from mhealthx.xio import read_accel_json >>> from mhealthx.signals import compute_sample_rate >>> input_file = '/Users/arno/DriveWork/mhealthx/mpower_sample_data/deviceMotion_walking_outbound.json.itemsa2ab93336d634676977a08591a5d837f5221783798792869048.tmp' >>> device_motion = True >>> start = 0 >>> t, axyz, gxyz, wxyz, rxyz, sample_rate, duration = read_accel_json(input_file, start, device_motion) >>> ax, ay, az = axyz >>> uw, ux, uy, uz = wxyz >>> from mhealthx.extractors.pyGait import project_walk_direction_attitude >>> px, py, pz = project_walk_direction_attitude(ax, ay, az, uw, ux, uy, uz)

mhealthx.extractors.pyGait.
project_walk_direction_preheel
(ax, ay, az, t, sample_rate, stride_fraction, threshold, order, cutoff)¶ Project accelerometer data on local walk (not cardinal) direction.
 NOTE::
 This calls walk_direction_preheel(), which computes a single walk direction. It does NOT estimate walking direction for every time point, like walk_direction_attitude().
 ax : numpy array
 accelerometer data along x axis
 ay : numpy array
 accelerometer data along y axis
 az : numpy array
 accelerometer data along z axis
 t : list or numpy array
 accelerometer time points
 sample_rate : float
 sample rate of accelerometer reading (Hz)
 stride_fraction : float
 fraction of stride assumed to be deceleration phase of primary leg
 threshold : float
 ratio to the maximum summed acceleration to extract peaks
 order : integer
 order of the Butterworth filter
 cutoff : integer
 cutoff frequency of the Butterworth filter (Hz)
 px : numpy array
 accelerometer data along x axis projected on unit vector
 py : numpy array
 accelerometer data along y axis projected on unit vector
 pz : numpy array
 accelerometer data along z axis projected on unit vector
>>> from mhealthx.xio import read_accel_json >>> from mhealthx.extractors.pyGait import project_walk_direction_preheel >>> input_file = '/Users/arno/DriveWork/mhealthx/mpower_sample_data/deviceMotion_walking_outbound.json.itemsa2ab93336d634676977a08591a5d837f5221783798792869048.tmp' >>> device_motion = True >>> start = 150 >>> t, axyz, gxyz, uxyz, rxyz, sample_rate, duration = read_accel_json(input_file, start, device_motion) >>> ax, ay, az = axyz >>> stride_fraction = 1.0/8.0 >>> threshold = 0.5 >>> order = 4 >>> cutoff = max([1, sample_rate/10]) >>> px, py, pz = project_walk_direction_preheel(ax, ay, az, t, sample_rate, stride_fraction, threshold, order, cutoff)

mhealthx.extractors.pyGait.
walk_direction_attitude
(ax, ay, az, uw, ux, uy, uz, plot_test=False)¶ Estimate local walk (not cardinal) directions by rotation with attitudes.
Translated by Arno Klein from Elias ChaibubNeto’s R code.
 ax : list or numpy array
 xaxis accelerometer data
 ay : list or numpy array
 yaxis accelerometer data
 az : list or numpy array
 zaxis accelerometer data
 uw : list or numpy array
 w of attitude quaternion
 ux : list or numpy array
 x of attitude quaternion
 uy : list or numpy array
 y of attitude quaternion
 uz : list or numpy array
 z of attitude quaternion
 plot_test : Boolean
 plot rotated vectors?
 directions : list of lists of three floats
 unit vector of local walk (not cardinal) direction at each time point
>>> from mhealthx.xio import read_accel_json >>> from mhealthx.signals import compute_sample_rate >>> input_file = '/Users/arno/DriveWork/mhealthx/mpower_sample_data/deviceMotion_walking_outbound.json.itemsa2ab93336d634676977a08591a5d837f5221783798792869048.tmp' >>> device_motion = True >>> start = 0 >>> t, axyz, gxyz, wxyz, rxyz, sample_rate, duration = read_accel_json(input_file, device_motion, start) >>> ax, ay, az = axyz >>> uw, ux, uy, uz = wxyz >>> from mhealthx.extractors.pyGait import walk_direction_attitude >>> plot_test = True >>> directions = walk_direction_attitude(ax, ay, az, uw, ux, uy, uz, plot_test)

mhealthx.extractors.pyGait.
walk_direction_preheel
(ax, ay, az, t, sample_rate, stride_fraction=0.125, threshold=0.5, order=4, cutoff=5, plot_test=False)¶ Estimate local walk (not cardinal) direction with preheel strike phase.
Inspired by Nirupam Roy’s B.E. thesis: “WalkCompass: Finding Walking Direction Leveraging Smartphone’s Inertial Sensors,” this program derives the local walk direction vector from the end of the primary leg’s stride, when it is decelerating in its swing. While the WalkCompass relies on clear heel strike signals across the accelerometer axes, this program just uses the most prominent strikes, and estimates period from the real part of the FFT of the data.
 NOTE::
 This algorithm computes a single walk direction, and could compute multiple walk directions prior to detected heel strikes, but does NOT estimate walking direction for every time point, like walk_direction_attitude().
 ax : list or numpy array
 xaxis accelerometer data
 ay : list or numpy array
 yaxis accelerometer data
 az : list or numpy array
 zaxis accelerometer data
 t : list or numpy array
 accelerometer time points
 sample_rate : float
 sample rate of accelerometer reading (Hz)
 stride_fraction : float
 fraction of stride assumed to be deceleration phase of primary leg
 threshold : float
 ratio to the maximum value of the summed acceleration across axes
 plot_test : Boolean
 plot most prominent heel strikes?
 direction : numpy array of three floats
 unit vector of local walk (not cardinal) direction
>>> from mhealthx.xio import read_accel_json >>> from mhealthx.signals import compute_sample_rate >>> input_file = '/Users/arno/DriveWork/mhealthx/mpower_sample_data/deviceMotion_walking_outbound.json.itemsa2ab93336d634676977a08591a5d837f5221783798792869048.tmp' >>> device_motion = True >>> start = 150 >>> t, axyz, gxyz, uxyz, rxyz, sample_rate, duration = read_accel_json(input_file, start, device_motion) >>> ax, ay, az = axyz >>> from mhealthx.extractors.pyGait import walk_direction_preheel >>> threshold = 0.5 >>> stride_fraction = 1.0/8.0 >>> order = 4 >>> cutoff = max([1, sample_rate/10]) >>> plot_test = True >>> direction = walk_direction_preheel(ax, ay, az, t, sample_rate, stride_fraction, threshold, order, cutoff, plot_test)