.. DO NOT EDIT. .. THIS FILE WAS AUTOMATICALLY GENERATED BY SPHINX-GALLERY. .. TO MAKE CHANGES, EDIT THE SOURCE PYTHON FILE: .. "auto_examples/stride_length/_01_sl_zijlstra.py" .. LINE NUMBERS ARE GIVEN BELOW. .. only:: html .. note:: :class: sphx-glr-download-link-note :ref:`Go to the end ` to download the full example code .. rst-class:: sphx-glr-example-title .. _sphx_glr_auto_examples_stride_length__01_sl_zijlstra.py: SL Zijlstra ============================= This example shows how to use the Zijlstra algorithm for calculating stride length and how its results compare to the original matlab implementation. Below we will demonstrate the usage of both methods. But first we load some data. Example Data ------------ We load example data from the lab dataset together with the INDIP reference system. We will use a single short-trail from the "HA" participant for this example, as it only contains a single gait sequence. The stride length algorithm is designed to work on a single gait sequence at a time. .. GENERATED FROM PYTHON SOURCE LINES 17-25 .. code-block:: default from mobgap.data import LabExampleDataset lab_example_data = LabExampleDataset(reference_system="INDIP") short_trial = lab_example_data.get_subset( cohort="HA", participant_id="001", test="Test5", trial="Trial2" ) .. GENERATED FROM PYTHON SOURCE LINES 26-30 SlZijlstra ---------- To demonstrate the usage of :class:`~mobgap.stride_length.SlZijlstra` we use the detected initial contacts from the reference system as input. .. GENERATED FROM PYTHON SOURCE LINES 30-33 .. code-block:: default reference_ic = short_trial.reference_parameters_relative_to_wb_.ic_list reference_ic .. raw:: html
ic lr_label
wb_id step_id
0 0 0 left
1 63 right
2 118 left
3 177 right
4 230 left
5 288 right
6 345 left
7 407 right
8 469 left


.. GENERATED FROM PYTHON SOURCE LINES 34-37 .. code-block:: default reference_gs = short_trial.reference_parameters_relative_to_wb_.wb_list reference_gs .. raw:: html
start end n_strides duration_s length_m avg_walking_speed_mps avg_cadence_spm avg_stride_length_m termination_reason
wb_id
0 392 862 7 4.69 4.76565 1.046655 103.453056 1.211187 Pause


.. GENERATED FROM PYTHON SOURCE LINES 38-39 We only pick the first gait sequence for this example. .. GENERATED FROM PYTHON SOURCE LINES 39-46 .. code-block:: default gs_id = reference_gs.index[0] data_in_gs = short_trial.data["LowerBack"].iloc[ reference_gs.start.iloc[0] : reference_gs.end.iloc[0] ] ics_in_gs = reference_ic.loc[gs_id] sensor_height = short_trial.participant_metadata["sensor_height_m"] .. GENERATED FROM PYTHON SOURCE LINES 47-49 Like most algorithms, the SlZijlstra requires the data to be in body frame coordinates. As we know the sensor was well aligned, we can just use ``to_body_frame`` to transform the data. .. GENERATED FROM PYTHON SOURCE LINES 49-53 .. code-block:: default from mobgap.utils.conversions import to_body_frame data_in_gs_bf = to_body_frame(data_in_gs) .. GENERATED FROM PYTHON SOURCE LINES 54-56 Then we initialize the algorithm and call the ``calculate`` method. We use the scaling parameters optimized on the MSProject dataset and leave all other values as default. .. GENERATED FROM PYTHON SOURCE LINES 56-69 .. code-block:: default from mobgap.stride_length import SlZijlstra sl_zijlstra = SlZijlstra( **SlZijlstra.PredefinedParameters.step_length_scaling_factor_ms_ms ) sl_zijlstra.calculate( data=data_in_gs_bf, initial_contacts=ics_in_gs, sensor_height_m=sensor_height, sampling_rate_hz=short_trial.sampling_rate_hz, ) .. rst-class:: sphx-glr-script-out .. code-block:: none SlZijlstra(acc_smoothing=ButterworthFilter(cutoff_freq_hz=0.1, filter_type='highpass', order=4, zero_phase=True), max_interpolation_gap_s=3, orientation_method=None, speed_smoothing=ButterworthFilter(cutoff_freq_hz=1, filter_type='highpass', order=4, zero_phase=True), step_length_scaling_factor=1.14675, step_length_smoothing=HampelFilter(half_window_size=2, n_sigmas=3.0)) .. GENERATED FROM PYTHON SOURCE LINES 70-72 We get an output that contains the stride length for each second of the gaits sequence. The index represents the sample of the center of the second the stride length value belongs to. .. GENERATED FROM PYTHON SOURCE LINES 72-74 .. code-block:: default sl_zijlstra.stride_length_per_sec_ .. raw:: html
stride_length_m
sec_center_samples
50 1.311806
150 1.257651
250 1.220031
350 1.195841
450 1.195841


.. GENERATED FROM PYTHON SOURCE LINES 75-77 To show that the approach results in roughly the "correct" stride length value, we can compare the average stride length to the reference system. .. GENERATED FROM PYTHON SOURCE LINES 77-83 .. code-block:: default reference_sl = reference_gs["avg_stride_length_m"].loc[gs_id] zijlstra_avg_sl = sl_zijlstra.stride_length_per_sec_["stride_length_m"].mean() print("Sensor frame:") print(f"Average stride length from reference: {reference_sl:.3f} m") print(f"Calculated average per-sec stride length: {zijlstra_avg_sl:.3f} m") .. rst-class:: sphx-glr-script-out .. code-block:: none Sensor frame: Average stride length from reference: 1.211 m Calculated average per-sec stride length: 1.236 m .. GENERATED FROM PYTHON SOURCE LINES 84-90 In addition, to this primary output, that is available for all stride length algorithms, the Zijlstra algorithm also provides some of the intermediate results that are used to calculate the stride length values. These might be helpful to generate further insides into the data or debug results. First it provides the step length values for each detected step, which is an annotated version of the input initial contacts. .. GENERATED FROM PYTHON SOURCE LINES 90-92 .. code-block:: default sl_zijlstra.raw_step_length_per_step_ .. raw:: html
ic lr_label step_length_m
step_id
0 0 left 0.655376
1 63 right 0.656429
2 118 left 0.616595
3 177 right 0.641056
4 230 left 0.603450
5 288 right 0.616582
6 345 left 0.597921
7 407 right 0.539340


.. GENERATED FROM PYTHON SOURCE LINES 93-95 Second, it provides the step length values for each second of the gait sequence. This is basically just half of the stride length values. .. GENERATED FROM PYTHON SOURCE LINES 95-97 .. code-block:: default sl_zijlstra.step_length_per_sec_ .. raw:: html
step_length_m
sec_center_samples
50 0.655903
150 0.628826
250 0.610016
350 0.597921
450 0.597921


.. GENERATED FROM PYTHON SOURCE LINES 98-121 Working in the global frame --------------------------- The algorithm assume that the accelerometer axes are aligned with the global reference system. I.e. that ``acc_x`` aligns with the vertical direction throughout the entire measurement. However, this assumption is not practical for the realworld measurement setup, even if an initial alignment is performed. The pelvis movement will always result in some changes in the orientation of the sensor. To overcome this, we can use a sensor orientation method to correct the sensor orientation to project the acceleration values to the global reference system. This is rarely perfect and might introduce some additional errors, but might help to improve the results overall. There are two ways to achieve this: 1. You could use an orientation method to correct the sensor orientation to the global reference system on the entire recording. This can often result in better orientation estimations, as the algorithm has time to converge, but might be computationally expensive. 2. Alternatively, you could use the ``orientation_method`` argument of ``SlZijlstra`` to apply a global frame transform only on the provided data. We will show this case below. We basically do the same above, but we correct the sensor orientation to the global frame using a Madgwick complementary filter, to show the improvement of performing re-orientation. .. GENERATED FROM PYTHON SOURCE LINES 121-133 .. code-block:: default from mobgap.orientation_estimation._madgwick import MadgwickAHRS sl_zijlstra_reoriented = SlZijlstra( orientation_method=MadgwickAHRS(beta=0.2), **SlZijlstra.PredefinedParameters.step_length_scaling_factor_ms_ms, ) sl_zijlstra_reoriented.calculate( data=data_in_gs_bf, initial_contacts=ics_in_gs, sensor_height_m=sensor_height, sampling_rate_hz=short_trial.sampling_rate_hz, ) .. rst-class:: sphx-glr-script-out .. code-block:: none SlZijlstra(acc_smoothing=ButterworthFilter(cutoff_freq_hz=0.1, filter_type='highpass', order=4, zero_phase=True), max_interpolation_gap_s=3, orientation_method=MadgwickAHRS(beta=0.2, initial_orientation=), speed_smoothing=ButterworthFilter(cutoff_freq_hz=1, filter_type='highpass', order=4, zero_phase=True), step_length_scaling_factor=1.14675, step_length_smoothing=HampelFilter(half_window_size=2, n_sigmas=3.0)) .. GENERATED FROM PYTHON SOURCE LINES 134-136 As before, we get an output that contains the stride length for each second of the gaits sequence. The index represents the sample of the center of the second the stride length value belongs to. .. GENERATED FROM PYTHON SOURCE LINES 136-138 .. code-block:: default sl_zijlstra_reoriented.stride_length_per_sec_ .. raw:: html
stride_length_m
sec_center_samples
50 1.316644
150 1.260432
250 1.225976
350 1.204895
450 1.204895


.. GENERATED FROM PYTHON SOURCE LINES 139-141 To show that the approach results in roughly the "correct" stride length value, we can compare the average stride length to the reference system. .. GENERATED FROM PYTHON SOURCE LINES 141-151 .. code-block:: default zijlstra_reoriented_avg_sl = sl_zijlstra_reoriented.stride_length_per_sec_[ "stride_length_m" ].mean() print("") print("Global frame:") print(f"Average stride length from reference: {reference_sl:.3f} m") print( f"Calculated average per-sec stride length: {zijlstra_reoriented_avg_sl:.3f} m" ) .. rst-class:: sphx-glr-script-out .. code-block:: none Global frame: Average stride length from reference: 1.211 m Calculated average per-sec stride length: 1.243 m .. GENERATED FROM PYTHON SOURCE LINES 152-154 Note, that in this case, the results did not really change between the version with and without Madgwick. However, this is not a general statement, but heavily depends on the data characteristics. .. rst-class:: sphx-glr-timing **Total running time of the script:** (0 minutes 4.446 seconds) **Estimated memory usage:** 10 MB .. _sphx_glr_download_auto_examples_stride_length__01_sl_zijlstra.py: .. only:: html .. container:: sphx-glr-footer sphx-glr-footer-example .. container:: sphx-glr-download sphx-glr-download-python :download:`Download Python source code: _01_sl_zijlstra.py <_01_sl_zijlstra.py>` .. container:: sphx-glr-download sphx-glr-download-jupyter :download:`Download Jupyter notebook: _01_sl_zijlstra.ipynb <_01_sl_zijlstra.ipynb>` .. only:: html .. rst-class:: sphx-glr-signature `Gallery generated by Sphinx-Gallery `_