.. DO NOT EDIT. .. THIS FILE WAS AUTOMATICALLY GENERATED BY SPHINX-GALLERY. .. TO MAKE CHANGES, EDIT THE SOURCE PYTHON FILE: .. "auto_examples/cadence/_01_cad_from_ic.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_cadence__01_cad_from_ic.py: .. _cad_from_ic: Cadence from Initial Contacts ============================= The most obvious way to calculate cadence is to use the detected initial contacts. However, initial contact (IC) detection from a single lower back sensor is never perfect. If we naively calculate cadence via a step time derived by "diffing" the initial contacts, missing ICs or even actual breaks in the gait sequence will lead to wrong cadence values (likely underestimating the cadence). We need to be robust to these types of errors. On the other hand, for the cadence estimation it is less important that the position of the IC within the stride is perfectly correct. This means, different IC detection methods might be optimal for the cadence estimation than for the IC detection itself. With these two things in mind, we implemented "Proxy" cadence algorithms that work on top of any IC detection method. Two variants exist: 1. :class:`~mobgap.algorithm.CadFromIc` calculates the cadence directly from the provided ICs using step-to-step smoothing to deal with missing ICs and breaks in the gait sequence. This method should be used, if you want to use the same IC detection method for the cadence estimation than for the IC detection itself (i.e. we are not rerunning any calculations, we just use the provided ICs). 2. :class:`~mobgap.algorithm.CadFromIcDetector` is a proxy algorithm that wraps around any IC detection algorithm. Compared to the previous method, this method will ignore the provided ICs and run the IC detection algorithm it wraps (which can be different from the one used for the IC detection itself) to find new ICs that are only used for the Cadence estimation. Both methods than use step-to-step smoothing to deal with missing ICs and breaks in the gait sequence and then interpolate all step time values to seconds to provide an average cadence for each one second interval of the recording. 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. All the cadence algorithms are designed to work on a single gait sequence at a time. .. GENERATED FROM PYTHON SOURCE LINES 42-50 .. code-block:: default from mobgap.data import LabExampleDataset lab_example_data = LabExampleDataset(reference_system="INDIP") short_trial: LabExampleDataset = lab_example_data.get_subset( cohort="HA", participant_id="001", test="Test5", trial="Trial2" ) .. GENERATED FROM PYTHON SOURCE LINES 51-55 CadFromIc --------- To demonstrate the usage of :class:`~mobgap.algorithm.CadFromIc` we use the detected initial contacts from the reference system as input. .. GENERATED FROM PYTHON SOURCE LINES 55-58 .. 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 59-62 .. 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 63-66 Then we initialize the algorithm and call the ``calculate`` method. Note that we use the ``sampling_rate_hz`` of the actual data and not the reference system. This is because, the reference parameters are already converted to the data sampling rate. .. GENERATED FROM PYTHON SOURCE LINES 66-82 .. code-block:: default from mobgap.cadence import CadFromIc cad_from_ic = CadFromIc() gs_id = reference_gs.index[0] data_in_gs = short_trial.data_ss.iloc[ reference_gs.start.iloc[0] : reference_gs.end.iloc[0] ] ics_in_gs = reference_ic[["ic"]].loc[gs_id] cad_from_ic.calculate( data_in_gs, initial_contacts=ics_in_gs, sampling_rate_hz=short_trial.sampling_rate_hz, ) .. rst-class:: sphx-glr-script-out .. code-block:: none CadFromIc(max_interpolation_gap_s=3, step_time_smoothing=HampelFilter(half_window_size=2, n_sigmas=3.0)) .. GENERATED FROM PYTHON SOURCE LINES 83-90 We get an output that contains the cadence for each second of the gaits sequence. The index represents the sample of the center of the second the cadence value belongs to. Note, that there might be NaNs in the output, if there are breaks in the gait sequence and further, that the final second might only be partially covered by the gait sequence. We still calculate a cadence value for the entire second, but it is only based on the steps that occur in the part that was actually covered by the gait sequence. .. GENERATED FROM PYTHON SOURCE LINES 90-92 .. code-block:: default cad_from_ic.cadence_per_sec_ .. raw:: html
cadence_spm
sec_center_samples
50 101.694915
150 107.142857
250 104.347826
350 96.774194
450 96.774194


.. GENERATED FROM PYTHON SOURCE LINES 93-95 To show that the approach results in roughly the "correct" cadence value, we can compare the average cadence to the reference system. .. GENERATED FROM PYTHON SOURCE LINES 95-102 .. code-block:: default reference_cad = reference_gs["avg_cadence_spm"].loc[gs_id] cad_from_ic_avg_cad = cad_from_ic.cadence_per_sec_["cadence_spm"].mean() print(f"Average stride cadence from reference: {reference_cad:.2f} steps/min") print( f"Calculated average per-sec cadence: {cad_from_ic_avg_cad:.2f} steps/min" ) .. rst-class:: sphx-glr-script-out .. code-block:: none Average stride cadence from reference: 103.45 steps/min Calculated average per-sec cadence: 101.35 steps/min .. GENERATED FROM PYTHON SOURCE LINES 103-112 Note that if we would have breaks in the gait sequence, the method would try to interpolate the cadence values for short breaks, but would provide NaNs for longer breaks. This is controlled by the ``max_interpolation_gap_s`` parameter. CadFromIcDetector ----------------- For the :class:`~mobgap.cadence.CadFromIcDetector` we need to supply an IC detection algorithm. In this case we use the :class:`~mobgap.initial_contacts.IcdShinImproved` algorithm. We could also use any other IC detection algorithm or adapt the parameters of the IC detection algorithm. .. GENERATED FROM PYTHON SOURCE LINES 112-117 .. code-block:: default from mobgap.cadence import CadFromIcDetector from mobgap.initial_contacts import IcdShinImproved cad_from_ic_detector = CadFromIcDetector(IcdShinImproved()) .. GENERATED FROM PYTHON SOURCE LINES 118-124 Now we can call the ``calculate`` method with the same data as before. Note, that we are still passing the initial contacts from the "previous" calculation step to fulfill the API. However, internally the algorithm will ignore the provided ICs and rerun the IC detection using the provided IC detector. Note, that we need to convert the data to the body frame, as the underlying IC-detector requires it. .. GENERATED FROM PYTHON SOURCE LINES 124-132 .. code-block:: default from mobgap.utils.conversions import to_body_frame cad_from_ic_detector.calculate( to_body_frame(data_in_gs), initial_contacts=ics_in_gs, sampling_rate_hz=short_trial.sampling_rate_hz, ) .. rst-class:: sphx-glr-script-out .. code-block:: none /home/docs/checkouts/readthedocs.org/user_builds/mobgap/checkouts/v0.9.0/examples/cadence/_01_cad_from_ic.py:126: UserWarning: This method ignores the passed initial contacts and recalculates them from the data. This way you can use a different IC detector for the cadence calculation than for the IC detection. If you don't want this, you should use the `CadFromIc` class instead. This warning is just a information to make sure you are fully aware of this. If you want to silence this warning, you can pass ``silence_ic_warning=True`` during the initialization of this class. cad_from_ic_detector.calculate( CadFromIcDetector(ic_detector=IcdShinImproved(axis='norm'), max_interpolation_gap_s=3, silence_ic_warning=False, step_time_smoothing=HampelFilter(half_window_size=2, n_sigmas=3.0)) .. GENERATED FROM PYTHON SOURCE LINES 133-140 .. note:: By default the ``CadFromIcDetector`` will raise a warning to inform the user that the passed ICs are ignored. This is intentionally, as we assume first time users might be confused by that fact. If you are aware of this and want to get rid of the warning, you can set ``silence_ic_warning`` to True on the ``CadFromIcDetector`` object. We get the same output structure as before. .. GENERATED FROM PYTHON SOURCE LINES 140-142 .. code-block:: default cad_from_ic_detector.cadence_per_sec_ .. raw:: html
cadence_spm
sec_center_samples
50 101.694915
150 106.194690
250 104.347826
350 97.560976
450 95.238095


.. GENERATED FROM PYTHON SOURCE LINES 143-144 But we can also access the detected initial contacts. .. GENERATED FROM PYTHON SOURCE LINES 144-146 .. code-block:: default cad_from_ic_detector.internal_ic_list_ .. raw:: html
ic
step_id
0 52
1 111
2 167
3 224
4 279
5 339
6 399
7 462


.. GENERATED FROM PYTHON SOURCE LINES 147-148 Or the entire detector object. .. GENERATED FROM PYTHON SOURCE LINES 148-150 .. code-block:: default cad_from_ic_detector.ic_detector_ .. rst-class:: sphx-glr-script-out .. code-block:: none IcdShinImproved(axis='norm') .. GENERATED FROM PYTHON SOURCE LINES 151-156 To show that the approach results in roughly the "correct" cadence value, we can compare the average cadence to the reference system. .. note:: Compared to the previous method, the cadence value are more different, as we actually run a IC detection algorithm to find the ICs and not just used the values provided by the reference. .. GENERATED FROM PYTHON SOURCE LINES 156-166 .. code-block:: default cad_from_ic_detector_avg_cad = cad_from_ic_detector.cadence_per_sec_[ "cadence_spm" ].mean() print(f"Average stride cadence from reference: {reference_cad:.2f} steps/min") print( f"Calculated average per-sec cadence (CadFromIC): {cad_from_ic_avg_cad:.2f} steps/min" ) print( f"Calculated average per-sec cadence (CadFromIcDetector): {cad_from_ic_detector_avg_cad:.2f} steps/min" ) .. rst-class:: sphx-glr-script-out .. code-block:: none Average stride cadence from reference: 103.45 steps/min Calculated average per-sec cadence (CadFromIC): 101.35 steps/min Calculated average per-sec cadence (CadFromIcDetector): 101.01 steps/min .. rst-class:: sphx-glr-timing **Total running time of the script:** (0 minutes 2.374 seconds) **Estimated memory usage:** 9 MB .. _sphx_glr_download_auto_examples_cadence__01_cad_from_ic.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_cad_from_ic.py <_01_cad_from_ic.py>` .. container:: sphx-glr-download sphx-glr-download-jupyter :download:`Download Jupyter notebook: _01_cad_from_ic.ipynb <_01_cad_from_ic.ipynb>` .. only:: html .. rst-class:: sphx-glr-signature `Gallery generated by Sphinx-Gallery `_