.. DO NOT EDIT. .. THIS FILE WAS AUTOMATICALLY GENERATED BY SPHINX-GALLERY. .. TO MAKE CHANGES, EDIT THE SOURCE PYTHON FILE: .. "auto_examples/gait_detection/ullrich_gait_sequence_detection.py" .. LINE NUMBERS ARE GIVEN BELOW. .. only:: html .. note:: :class: sphx-glr-download-link-note Click :ref:`here ` to download the full example code .. rst-class:: sphx-glr-example-title .. _sphx_glr_auto_examples_gait_detection_ullrich_gait_sequence_detection.py: Ullrich gait sequence detection =============================== This example illustrates how the gait sequence detection by the :class:`~gaitmap.gait_detection.UllrichGaitSequenceDetection` can be used to detect gait sequences within an IMU signal stream. The used implementation is based on the work of Ullrich et al. [1]_. The underlying algorithm works under the assumption that the IMU gait signal shows a characteristic pattern of harmonics when looking at the power spectral density. This is in contrast to cyclic non-gait signals, where there is usually only one dominant frequency present. .. [1] Ullrich, M., Küderle, A., Hannink, J., Del Din, S., Gaßner, H., Marxreiter, F., Klucken, J., Eskofier,B. M. & Kluge, F. (2020). Detection of Gait From Continuous Inertial Sensor Data Using Harmonic Frequencies. IEEE Journal of Biomedical and Health Informatics, 24(7), 1869-1878. https://doi.org/10.1109/JBHI.2020.2975361 .. GENERATED FROM PYTHON SOURCE LINES 19-27 Getting some example data ------------------------- For this we take some example data that contains the regular walking movement during a 2x20m walk test of a healthy subject. The IMU signals are already rotated so that they align with the gaitmap SF coordinate system. The data contains information from two sensors - one from the right and one from the left foot. For further information regarding the coordinate system refer to the :ref:`coordinate system guide`. .. GENERATED FROM PYTHON SOURCE LINES 27-33 .. code-block:: default from gaitmap.example_data import get_healthy_example_imu_data data = get_healthy_example_imu_data() sampling_rate_hz = 204.8 data.sort_index(axis=1).head(1) .. raw:: html
sensor left_sensor right_sensor
axis acc_x acc_y acc_z gyr_x gyr_y gyr_z acc_x acc_y acc_z gyr_x gyr_y gyr_z
0.0 0.880811 2.762208 9.40865 -0.112402 -0.032157 -0.062261 0.311553 -2.398646 9.513275 -0.323037 0.084604 -0.025288


.. GENERATED FROM PYTHON SOURCE LINES 34-40 Preparing the data ------------------ The data is expected to be in the gaitmap BF to be able to use the same template for the left and the right foot. Therefore, we need to transform the dataset into the body frame. For further information regarding the coordinate system refer to the :ref:`coordinate system guide`. .. GENERATED FROM PYTHON SOURCE LINES 40-50 .. code-block:: default from gaitmap.utils.coordinate_conversion import convert_to_fbf # We use the `..._like` parameters to identify the data of the left and the right foot based on the name of the sensor. bf_data = convert_to_fbf(data, left_like="left_", right_like="right_") # for demonstration purposes we will for now stick with the data of one foot only bf_data = bf_data["left_sensor"] import numpy as np .. GENERATED FROM PYTHON SOURCE LINES 51-56 Add rest and non-gait data -------------------------- Additionally to the gait data we use some artificial signal to simulate rest and an arbitrary cyclic but non-gait movement. .. GENERATED FROM PYTHON SOURCE LINES 56-74 .. code-block:: default import pandas as pd # use zeros for rest rest_df = pd.DataFrame([[0] * bf_data.shape[1]], columns=bf_data.columns) rest_df = pd.concat([rest_df] * 2048) # create a sine signal to mimic non-gait samples = 2048 t = np.arange(samples) / sampling_rate_hz freq = 1 test_signal = np.sin(2 * np.pi * freq * t) * 200 test_signal_reshaped = np.tile(test_signal, (bf_data.shape[1], 1)).T non_gait_df = pd.DataFrame(test_signal_reshaped, columns=bf_data.columns) # combine rest, gait and non-gait data to one dataframe test_data_df = pd.concat([rest_df, bf_data, rest_df, non_gait_df, rest_df, bf_data, rest_df], ignore_index=True) test_data_df.head(1) .. raw:: html
acc_pa acc_ml acc_si gyr_pa gyr_ml gyr_si
0 0.0 0.0 0.0 0.0 0.0 0.0


.. GENERATED FROM PYTHON SOURCE LINES 75-91 Applying the gait sequence detection ------------------------------------ First we need to initialize the Ullrich gait sequence detection. In most cases it is sufficient to keep all parameters at default. These are set as presented in the original paper. In correspondence with the original publication usually the `gyr_ml` signal is investigated regarding the presence of gait. It is however also possible to use `gyr` or `acc` in order to apply the algorithm to the signal norm of gyroscope or accelerometer, respectively. Furthermore the `acc_si` was investigated in the paper. The optimal value for the `peak_prominence` which serves as a threshold for the harmonic frequency peaks was found to be `17` in the publication for the `gyr_ml` setting. All experiments in the paper were performed with a `window_size_s` of `10 s`, where subsequent windows were overlapping by 50%. The default value for the `active_signal_threshold` was found experimentally and is per default set to `50 deg/s` for the usage of `gyr_ml`. The algorithm first identifies the dominant frequency of the signal window, which should usually be within the `locomotion_band` of `(0.5 3) Hz`. For very slow gait, the lower bound may have to be decreased. .. GENERATED FROM PYTHON SOURCE LINES 91-96 .. code-block:: default from gaitmap.gait_detection import UllrichGaitSequenceDetection gsd = UllrichGaitSequenceDetection() gsd = gsd.detect(data=test_data_df, sampling_rate_hz=sampling_rate_hz) .. rst-class:: sphx-glr-script-out .. code-block:: none /home/docs/checkouts/readthedocs.org/user_builds/gaitmap/envs/v2.5.2/lib/python3.9/site-packages/gaitmap_mad/gait_detection/_ullrich_gait_sequence_detection.py:384: PeakPropertyWarning: some peaks have a prominence of 0 peak_prominence = peak_prominences(f_s_1d_flat, closest_peaks)[0].reshape(harmonics_candidates.shape) .. GENERATED FROM PYTHON SOURCE LINES 97-102 Inspecting the results ---------------------- The main output is `gait_sequences_`, which is a `RegionsOfInterestList` that contains the samples of `start` and `end` of all detected gait sequences. It furthermore has a column `gs_id` for the gait sequence id which is used in further processing steps to assign for example single strides to their respective `gs_id`. .. GENERATED FROM PYTHON SOURCE LINES 102-106 .. code-block:: default gait_sequences = gsd.gait_sequences_ print(f"{len(gait_sequences)} gait sequences were detected.") gait_sequences.head() .. rst-class:: sphx-glr-script-out .. code-block:: none 2 gait sequences were detected. .. raw:: html
gs_id start end
0 0 2048 10240
1 1 15360 23552


.. GENERATED FROM PYTHON SOURCE LINES 107-109 To get a better understanding of the results, we can plot the data and the gait detected gait sequences. The vertical lines show the start and end of the gait sequences. .. GENERATED FROM PYTHON SOURCE LINES 109-133 .. code-block:: default import matplotlib.pyplot as plt fig, ax1 = plt.subplots(1, sharex=True, figsize=(10, 5)) ax1.plot(test_data_df["gyr_ml"], label="gyr_ml") start_idx = gait_sequences["start"].to_numpy().astype(int) end_idx = gait_sequences["end"].to_numpy().astype(int) for _i, gs in gait_sequences.iterrows(): start_sample = int(gs["start"]) end_sample = int(gs["end"]) ax1.axvline(start_sample, color="g") ax1.axvline(end_sample, color="r") ax1.axvspan(start_sample, end_sample, facecolor="grey", alpha=0.8) ax1.grid(True) ax1.set_title("Detected gait sequences") ax1.set_ylabel("gyr_ml (°/s)") plt.legend(loc="best") fig.tight_layout() fig.show() .. image-sg:: /auto_examples/gait_detection/images/sphx_glr_ullrich_gait_sequence_detection_001.png :alt: Detected gait sequences :srcset: /auto_examples/gait_detection/images/sphx_glr_ullrich_gait_sequence_detection_001.png :class: sphx-glr-single-img .. rst-class:: sphx-glr-timing **Total running time of the script:** ( 0 minutes 8.918 seconds) **Estimated memory usage:** 11 MB .. _sphx_glr_download_auto_examples_gait_detection_ullrich_gait_sequence_detection.py: .. only:: html .. container:: sphx-glr-footer sphx-glr-footer-example .. container:: sphx-glr-download sphx-glr-download-python :download:`Download Python source code: ullrich_gait_sequence_detection.py ` .. container:: sphx-glr-download sphx-glr-download-jupyter :download:`Download Jupyter notebook: ullrich_gait_sequence_detection.ipynb ` .. only:: html .. rst-class:: sphx-glr-signature `Gallery generated by Sphinx-Gallery `_