.. DO NOT EDIT. .. THIS FILE WAS AUTOMATICALLY GENERATED BY SPHINX-GALLERY. .. TO MAKE CHANGES, EDIT THE SOURCE PYTHON FILE: .. "auto_examples/cad/_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_cad__01_cad_from_ic.py: 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 40-48 .. 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 49-53 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 53-56 .. 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
1 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 57-60 .. 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_speed_mps avg_cadence_spm avg_stride_length_m termination_reason
wb_id
1 392 862 7 4.69 4.76565 1.046655 103.453056 1.211187 Pause


.. GENERATED FROM PYTHON SOURCE LINES 61-64 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 64-74 .. code-block:: default from mobgap.cad import CadFromIc cad_from_ic = CadFromIc() 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[["ic"]].loc[gs_id] cad_from_ic.calculate(data_in_gs, 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.2.0/mobgap/cad/_cad_from_ic.py:183: UserWarning: Usually we assume that gait sequences are cut to the first and last detected initial contact. This is not the case for the passed initial contacts and might lead to unexpected results in the cadence calculation. Specifically, you will get NaN values at the start and the end of the output. initial_contacts = self._get_ics(data, initial_contacts, sampling_rate_hz)["ic"] CadFromIc(max_interpolation_gap_s=3, step_time_smoothing=HampelFilter(half_window_size=2, n_sigmas=3.0)) .. GENERATED FROM PYTHON SOURCE LINES 75-77 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. .. GENERATED FROM PYTHON SOURCE LINES 77-79 .. code-block:: default cad_from_ic.cad_per_sec_ .. raw:: html
cad_spm
sec_center_samples
50 101.694915
150 107.142857
250 104.347826
350 96.774194


.. GENERATED FROM PYTHON SOURCE LINES 80-82 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 82-87 .. code-block:: default reference_cad = reference_gs["avg_cadence_spm"].loc[gs_id] cad_from_ic_avg_cad = cad_from_ic.cad_per_sec_["cad_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: 102.49 steps/min .. GENERATED FROM PYTHON SOURCE LINES 88-97 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.cad.CadFromIcDetector` we need to supply an IC detection algorithm. In this case we use the :class:`~mobgap.icd.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 97-102 .. code-block:: default from mobgap.cad import CadFromIcDetector from mobgap.icd import IcdShinImproved cad_from_ic_detector = CadFromIcDetector(IcdShinImproved()) .. GENERATED FROM PYTHON SOURCE LINES 103-107 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. .. GENERATED FROM PYTHON SOURCE LINES 107-109 .. code-block:: default cad_from_ic_detector.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 /home/docs/checkouts/readthedocs.org/user_builds/mobgap/checkouts/v0.2.0/examples/cad/_01_cad_from_ic.py:107: 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(data_in_gs, initial_contacts=ics_in_gs, sampling_rate_hz=short_trial.sampling_rate_hz) 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 110-117 .. 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 117-119 .. code-block:: default cad_from_ic_detector.cad_per_sec_ .. raw:: html
cad_spm
sec_center_samples
50 101.694915
150 106.194690
250 104.347826
350 97.560976


.. GENERATED FROM PYTHON SOURCE LINES 120-121 But we can also access the detected initial contacts. .. GENERATED FROM PYTHON SOURCE LINES 121-123 .. 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 124-125 Or the entire detector object. .. GENERATED FROM PYTHON SOURCE LINES 125-127 .. 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 128-133 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 133-137 .. code-block:: default cad_from_ic_detector_avg_cad = cad_from_ic_detector.cad_per_sec_["cad_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): 102.49 steps/min Calculated average per-sec cadence (CadFromIcDetector): 102.45 steps/min .. rst-class:: sphx-glr-timing **Total running time of the script:** (0 minutes 3.988 seconds) **Estimated memory usage:** 13 MB .. _sphx_glr_download_auto_examples_cad__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 `_