Note
Click here to download the full example code
Gait Analysis Pipeline for Signia Hearing Aid Data#
This example illustrates how the gait analysis pipeline by the EarGait
can be applied to data recorded with Signia Hearing Aids.
The used gait event detection method is based on the work of Diao et al. [1] with a few adaptations as described in DiaoAdaptedEventDetection
Getting some example data#
For this we take some example data that contains regular walking movements.
import pandas as pd
from eargait.preprocessing import align_gravity_and_convert_ear_to_ebf, load
from eargait.utils.example_data import get_mat_example_data_path
# path to data file (.txt or .mat) or data directory (only for .mat)
data_path = get_mat_example_data_path()
Loading the data#
A data session refers to a recording by signia hearing aids.
A session can consist of a single *.txt or *.mat file, or two *.mat files, for left and right ear, respectively.
The session is loaded using the local path data_path of the directory, in which the matlab/txt file(s) are stored.
For more options regarding loading the data see Load Data by Signia Hearing Aids.
target_sample_rate = 50
session = load(data_path, target_sample_rate_hz=target_sample_rate, skip_calibration=True)
session.info
/home/docs/checkouts/readthedocs.org/user_builds/eargait/checkouts/latest/eargait/preprocessing/load_data_helpers.py:54: UserWarning: Calibration was skipped. Calibration is strongly recommended.
warnings.warn("Calibration was skipped. Calibration is strongly recommended.")
<signialib.header._ProxyHeader object at 0x7ff642ea92b0>
Gravity alignment and data transformation into body frame#
Align session to gravity and transform coordinate system into body frame Alternatively, you can skip the gravity alignment by using the following function: convert_ear_to_ebf Alternatively, you can you the following function for gravity alignment: StaticWindowGravityAlignment
from eargait.utils import StaticWindowGravityAlignment, TrimMeanGravityAlignment
gravity_method = TrimMeanGravityAlignment(target_sample_rate)
ear_data = align_gravity_and_convert_ear_to_ebf(session, gravity_method)
# Alternatively, you can skip the gravity alignment by using the following function: convert_ear_to_ebf
# ear_data = convert_ear_to_ebf(session)
Extract walking interval#
Note: Here prior knowledge about walking sequence within the given data session are applied. Load csv file containing walking bouts.
rescale_factor = 200 / target_sample_rate
walking_bout_list = pd.read_csv(data_path.parent.joinpath("walking_bout_indices.csv"))
interval = (int(walking_bout_list["start"][0] / rescale_factor), int(walking_bout_list["stop"][0] / rescale_factor))
# alternative if walking bout indices are already known, e.g.
# interval = (14317, 17637) --> indices need to be replaced based on data
ear_data_short = {}
for side in ear_data.keys():
ear_data_short[side] = ear_data[side][interval[0] : interval[1]]
Initializing event detection algorithm#
Recommended parameters:
apply filter = True,
sampling_rate_hz needs to correspond to target_sample_rate_hz,
* window_length` should be equal to sampling_rate_hz.
from eargait.event_detection import DiaoAdaptedEventDetection
event_detection_algorithm = DiaoAdaptedEventDetection(
sample_rate_hz=target_sample_rate, window_length=target_sample_rate
)
Initializing spatial parameter estimation method#
Needs to be implemented by user if spatial parameters want to be estimated. SpatialParamsRandomForest is the recommended method. Alternatively, you can use one of the following methods: SpatialParamsRandomForestDemographics, SpatialParamsCNN
from eargait.spatial_params import SpatialParamsRandomForest
spatial_method = SpatialParamsRandomForest(target_sample_rate)
Initializing Gait Analysis Pipeline#
Recommended parameters:
sampling_rate_hz`needs to correspond to `target_sample_rate_hz.
from eargait import EarGait
ear_gait = EarGait(
sample_rate_hz=target_sample_rate,
event_detection_method=event_detection_algorithm,
spatial_params_method=spatial_method,
bool_use_event_list_consistent=True,
)
Detect gait events of gait sequence#
ear_gait.detect(ear_data_short)
gait_events = ear_gait.event_list
gait_events
{'right_sensor': ic tc side
s_id
0 3705.0 NaN contralateral
1 3730.0 3710.0 ipsilateral
2 3755.0 3735.0 contralateral
3 3780.0 3759.0 ipsilateral
4 3804.0 3784.0 contralateral
5 3828.0 3808.0 ipsilateral
6 3853.0 3832.0 contralateral
7 3877.0 3856.0 ipsilateral
8 3901.0 3881.0 contralateral
9 3926.0 3905.0 ipsilateral
10 3951.0 3930.0 contralateral
11 3975.0 3966.0 ipsilateral
12 3995.0 3981.0 contralateral
13 4019.0 4001.0 ipsilateral
14 4044.0 4022.0 contralateral
15 4069.0 4048.0 ipsilateral
16 4093.0 4073.0 contralateral
17 4118.0 4097.0 ipsilateral
18 4142.0 4121.0 contralateral
19 4167.0 4147.0 ipsilateral
20 4192.0 4171.0 contralateral
21 4216.0 4196.0 ipsilateral
22 4241.0 4220.0 contralateral, 'left_sensor': ic tc side
s_id
0 3705.0 NaN ipsilateral
1 3730.0 3710.0 contralateral
2 3755.0 3735.0 ipsilateral
3 3780.0 3759.0 contralateral
4 3804.0 3783.0 ipsilateral
5 3828.0 3808.0 contralateral
6 3852.0 3832.0 ipsilateral
7 3877.0 3856.0 contralateral
8 3901.0 3881.0 ipsilateral
9 3925.0 3905.0 contralateral
10 NaN NaN ipsilateral
11 NaN NaN ipsilateral
12 4019.0 NaN contralateral
13 4044.0 4022.0 ipsilateral
14 4068.0 4048.0 contralateral
15 4093.0 4072.0 ipsilateral
16 4117.0 4096.0 contralateral
17 4142.0 4121.0 ipsilateral
18 4166.0 4146.0 contralateral
19 4191.0 4170.0 ipsilateral
20 4216.0 4196.0 contralateral
21 4241.0 4219.0 ipsilateral}
Get all gait parameters#
gait_params = ear_gait.get_gait_parameters()
gait_params
{'right_sensor': stride_time 0.973333
stance_time 0.580000
swing_time 0.393333
step_time 0.487273
step_length 0.776785
stride_length 1.561183
gait_velocity 1.594277
number_of_steps 23.000000
cadence 123.134328
cadence_dom_freq 125.000000
stride_time_asymmetry 0.002545
stance_time_asymmetry 0.015273
swing_time_asymmetry 0.017818
step_time_asymmetry 0.007273
step_length_asymmetry 0.009432
stride_length_asymmetry 0.003819
gait_velocity_asymmetry 0.006005
stride_time_asymmetry_percent 0.002615
stance_time_asymmetry_percent 0.026332
swing_time_asymmetry_percent 0.045300
step_time_asymmetry_percent 0.014925
step_length_asymmetry_percent 0.012143
stride_length_asymmetry_percent 0.002446
gait_velocity_asymmetry_percent 0.003766
stride_time_si 0.261536
stance_time_si 2.631579
swing_time_si 4.534938
step_time_si 1.492537
step_length_si 1.214298
stride_length_si 0.244645
gait_velocity_si 0.376638
stride_time_std 0.033066
stance_time_std 0.053666
swing_time_std 0.058765
step_time_std 0.021861
step_length_std 0.082807
stride_length_std 0.165710
gait_velocity_std 0.155541
stride_time_cv 0.033971
stance_time_cv 0.092527
swing_time_cv 0.149403
step_time_cv 0.044865
step_length_cv 0.106602
stride_length_cv 0.106144
gait_velocity_cv 0.097562
dtype: float64, 'left_sensor': stride_time 1.034118
stance_time 0.570000
swing_time 0.412941
step_time 0.491111
step_length 0.814682
stride_length 1.644055
gait_velocity 1.660167
number_of_steps 22.000000
cadence 117.537313
cadence_dom_freq 125.000000
stride_time_asymmetry 0.097500
stance_time_asymmetry 0.005000
swing_time_asymmetry 0.010278
step_time_asymmetry 0.004444
step_length_asymmetry 0.001637
stride_length_asymmetry 0.027742
gait_velocity_asymmetry 0.018433
stride_time_asymmetry_percent 0.094283
stance_time_asymmetry_percent 0.008772
swing_time_asymmetry_percent 0.024889
step_time_asymmetry_percent 0.009050
step_length_asymmetry_percent 0.002009
stride_length_asymmetry_percent 0.016874
gait_velocity_asymmetry_percent 0.011103
stride_time_si 9.454545
stance_time_si 0.877193
swing_time_si 2.490744
step_time_si 0.904977
step_length_si 0.200888
stride_length_si 1.686572
gait_velocity_si 1.110340
stride_time_std 0.218376
stance_time_std 0.014606
swing_time_std 0.014038
step_time_std 0.010226
step_length_std 0.050290
stride_length_std 0.081367
gait_velocity_std 0.116777
stride_time_cv 0.211172
stance_time_cv 0.025624
swing_time_cv 0.033995
step_time_cv 0.020823
step_length_cv 0.061730
stride_length_cv 0.049492
gait_velocity_cv 0.070340
dtype: float64}
Get temporal gait parameters of gait sequence#
temporal_params = ear_gait.temporal_params
temporal_params
{'right_sensor': stride_time stance_time swing_time step_time side
s_id
0 NaN NaN NaN NaN contralateral
1 NaN NaN NaN 0.50 ipsilateral
2 1.00 0.60 0.40 0.50 contralateral
3 1.00 0.58 0.42 0.50 ipsilateral
4 0.98 0.58 0.40 0.48 contralateral
5 0.96 0.56 0.40 0.48 ipsilateral
6 0.98 0.56 0.42 0.50 contralateral
7 0.98 0.56 0.42 0.48 ipsilateral
8 0.96 0.56 0.40 0.48 contralateral
9 0.98 0.56 0.42 0.50 ipsilateral
10 1.00 0.58 0.42 0.50 contralateral
11 0.98 0.80 0.18 0.48 ipsilateral
12 0.88 0.60 0.28 0.40 contralateral
13 0.88 0.52 0.36 0.48 ipsilateral
14 0.98 0.54 0.44 0.50 contralateral
15 1.00 0.58 0.42 0.50 ipsilateral
16 0.98 0.58 0.40 0.48 contralateral
17 0.98 0.56 0.42 0.50 ipsilateral
18 0.98 0.56 0.42 0.48 contralateral
19 0.98 0.58 0.40 0.50 ipsilateral
20 1.00 0.58 0.42 0.50 contralateral
21 0.98 0.58 0.40 0.48 ipsilateral
22 0.98 0.56 0.42 0.50 contralateral, 'left_sensor': stride_time stance_time swing_time step_time side
s_id
0 NaN NaN NaN NaN ipsilateral
1 NaN NaN NaN 0.50 contralateral
2 1.00 0.60 0.40 0.50 ipsilateral
3 1.00 0.58 0.42 0.50 contralateral
4 0.98 0.56 0.42 0.48 ipsilateral
5 0.96 0.56 0.40 0.48 contralateral
6 0.96 0.56 0.40 0.48 ipsilateral
7 0.98 0.56 0.42 0.50 contralateral
8 0.98 0.58 0.40 0.48 ipsilateral
9 0.96 0.56 0.40 0.48 contralateral
10 NaN NaN NaN NaN ipsilateral
11 NaN NaN NaN NaN ipsilateral
12 1.88 NaN NaN NaN contralateral
13 NaN NaN 0.44 0.50 ipsilateral
14 0.98 0.58 0.40 0.48 contralateral
15 0.98 0.56 0.42 0.50 ipsilateral
16 0.98 0.56 0.42 0.48 contralateral
17 0.98 0.56 0.42 0.50 ipsilateral
18 0.98 0.58 0.40 0.48 contralateral
19 0.98 0.56 0.42 0.50 ipsilateral
20 1.00 0.60 0.40 0.50 contralateral
21 1.00 0.56 0.44 0.50 ipsilateral}
Get average temporal gait parameters#
{'right_sensor': stride_time stance_time swing_time step_time
mean 0.973333 0.580000 0.393333 0.487273
std 0.033066 0.053666 0.058765 0.021861, 'left_sensor': stride_time stance_time swing_time step_time
mean 1.034118 0.570000 0.412941 0.491111
std 0.218376 0.014606 0.014038 0.010226}
Get spatial parameter for walking bout#
spatial_params = ear_gait.spatial_params
spatial_params
{'right_sensor': step_length stride_length gait_velocity side
s_id
0 NaN NaN NaN contralateral
1 0.695014 1.390028 1.390028 ipsilateral
2 0.764706 1.529411 1.529411 contralateral
3 0.828608 1.657215 1.657215 ipsilateral
4 0.826527 1.653053 1.721931 contralateral
5 0.834984 1.669969 1.739551 ipsilateral
6 0.861254 1.722507 1.722507 contralateral
7 0.829787 1.659573 1.728722 ipsilateral
8 0.820857 1.641714 1.710119 contralateral
9 0.791892 1.583785 1.583785 ipsilateral
10 0.630941 1.261883 1.261883 contralateral
11 0.601177 1.202353 1.252451 ipsilateral
12 0.618608 1.237217 1.546521 contralateral
13 0.682579 1.365158 1.422040 ipsilateral
14 0.795314 1.590628 1.590628 contralateral
15 0.831986 1.663971 1.663971 ipsilateral
16 0.823938 1.647875 1.716537 contralateral
17 0.862365 1.724730 1.724730 ipsilateral
18 0.831871 1.663742 1.733065 contralateral
19 0.854592 1.709184 1.709184 ipsilateral
20 0.821898 1.643796 1.643796 contralateral
21 0.783526 1.567053 1.632346 ipsilateral
22 0.696839 NaN 1.393679 contralateral, 'left_sensor': step_length stride_length gait_velocity side
s_id
0 NaN NaN NaN ipsilateral
1 0.691622 1.383244 1.383244 contralateral
2 0.778696 1.557393 1.557393 ipsilateral
3 0.838782 1.677563 1.677563 contralateral
4 0.839790 1.679580 1.749563 ipsilateral
5 0.835447 1.670893 1.740514 contralateral
6 0.850304 1.700608 1.771466 ipsilateral
7 0.858543 1.717087 1.717087 contralateral
8 0.818064 1.636128 1.704300 ipsilateral
9 0.796490 1.592980 1.659355 contralateral
10 NaN NaN NaN ipsilateral
11 NaN NaN NaN ipsilateral
12 NaN NaN NaN contralateral
13 0.801564 1.603127 1.603127 ipsilateral
14 0.832159 1.664318 1.733665 contralateral
15 0.848087 1.696173 1.696173 ipsilateral
16 0.850186 1.700373 1.771222 contralateral
17 0.858651 1.717302 1.717302 ipsilateral
18 0.831188 1.662375 1.731641 contralateral
19 0.839812 1.679623 1.679623 ipsilateral
20 0.805082 1.610164 1.610164 contralateral
21 0.689803 NaN 1.379606 ipsilateral}
Get average spatial parameter over walking bout#
spatial_params_average = ear_gait.average_spatial_params
spatial_params_average
{'right_sensor': step_length stride_length gait_velocity
mean 0.776785 1.561183 1.594277
std 0.082807 0.165710 0.155541, 'left_sensor': step_length stride_length gait_velocity
mean 0.814682 1.644055 1.660167
std 0.050290 0.081367 0.116777}
Get cadence (num steps/duration)#
{'right_sensor': 123.13432835820896, 'left_sensor': 117.53731343283582}
Get cadence based on the dominant frequency#
{'right_sensor': 124.99999999999999, 'left_sensor': 124.99999999999999}
Get asymmetry, symetry index or variability#
symmetry_index = ear_gait.get_symmetry_index()
symmetry_index
# same for ear_gait.get_variability(), ear_gait.get_asymmetry()
{'right_sensor': stride_time_si 0.261536
stance_time_si 2.631579
swing_time_si 4.534938
step_time_si 1.492537
step_length_si 1.214298
stride_length_si 0.244645
gait_velocity_si 0.376638
dtype: float64, 'left_sensor': stride_time_si 9.454545
stance_time_si 0.877193
swing_time_si 2.490744
step_time_si 0.904977
step_length_si 0.200888
stride_length_si 1.686572
gait_velocity_si 1.110340
dtype: float64}
Plotting gait events#
ear_gait.plot()
k = 1
Total running time of the script: ( 0 minutes 8.682 seconds)
Estimated memory usage: 13 MB

