.. DO NOT EDIT. .. THIS FILE WAS AUTOMATICALLY GENERATED BY SPHINX-GALLERY. .. TO MAKE CHANGES, EDIT THE SOURCE PYTHON FILE: .. "auto_examples/pipeline/_02_step_by_step_mobilised_pipeline.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_pipeline__02_step_by_step_mobilised_pipeline.py: .. _mobilised_pipeline_step_by_step: The Mobilise-D pipeline: Step-by-Step Breakdown =============================================== This example shows how to build a full gait analysis pipeline using the mobgap package. Note, that we provide pre-built pipelines for common use-cases. Checkout the examples for those, if you want to understand how to use them. This example is meant to provide a better understanding of the individual steps and should serve as a blueprint to build completely custom pipelines. We are following the pipeline explained in [1]_ (Fig. 7) step by step. For more information about the individual steps, please refer to the respective examples for the algorithms. .. [1] Kirk, C., Küderle, A., Micó-Amigo, M.E. et al. Mobilise-D insights to estimate real-world walking speed in multiple conditions with a wearable device. Sci Rep 14, 1754 (2024). https://doi.org/10.1038/s41598-024-51766-5 .. GENERATED FROM PYTHON SOURCE LINES 24-33 Load example data ----------------- We load example data from the lab dataset, and we will use a single long-trail from an "MS" participant for this example. Note, that we directly convert it into the body frame, as bascially all algorithms require the body frame data (and all others support it). We can do that, because we know that the data is already well aligned with the sensor frame conventions. If this would not be the case, the data would need to be rotated/algigned before running through the pipeline. .. GENERATED FROM PYTHON SOURCE LINES 33-46 .. code-block:: Python import pandas as pd from mobgap.data import LabExampleDataset from mobgap.utils.conversions import to_body_frame from mobgap.utils.interpolation import naive_sec_paras_to_regions lab_example_data = LabExampleDataset(reference_system="INDIP") long_trial = lab_example_data.get_subset( cohort="MS", participant_id="001", test="Test11", trial="Trial1" ) imu_data = to_body_frame(long_trial.data_ss) sampling_rate_hz = long_trial.sampling_rate_hz participant_metadata = long_trial.participant_metadata .. GENERATED FROM PYTHON SOURCE LINES 47-49 Step 1: Gait Sequence Detection ------------------------------- .. GENERATED FROM PYTHON SOURCE LINES 49-57 .. code-block:: Python from mobgap.gait_sequences import GsdIluz gsd = GsdIluz() gsd.detect(imu_data, sampling_rate_hz=sampling_rate_hz) gait_sequences = gsd.gs_list_ gait_sequences .. raw:: html
start end
gs_id
0 900 2101
1 4650 6151
2 9600 10801
3 11250 12151
4 12300 14851
5 19950 21151
6 21300 22501


.. GENERATED FROM PYTHON SOURCE LINES 58-60 Starting from here, all the processing will happen per gait sequence. We will go through the steps just for a single gait sequence first and later put everything in a loop. .. GENERATED FROM PYTHON SOURCE LINES 60-66 .. code-block:: Python first_gait_sequence = gait_sequences.iloc[0] first_gait_sequence_data = imu_data.iloc[ first_gait_sequence.start : first_gait_sequence.end ] .. GENERATED FROM PYTHON SOURCE LINES 67-69 Step 2: Initial Contact Detection --------------------------------- .. GENERATED FROM PYTHON SOURCE LINES 69-77 .. code-block:: Python from mobgap.initial_contacts import IcdShinImproved icd = IcdShinImproved() icd.detect(first_gait_sequence_data, sampling_rate_hz=sampling_rate_hz) ic_list = icd.ic_list_ ic_list .. raw:: html
ic
step_id
0 86
1 158
2 216
3 271
4 326
5 381
6 441
7 496
8 560
9 621
10 696
11 795
12 870
13 949
14 1036
15 1131
16 1191


.. GENERATED FROM PYTHON SOURCE LINES 78-81 Step 2.5: Laterality Detection ------------------------------ For each IC we want to detect the laterality. .. GENERATED FROM PYTHON SOURCE LINES 81-89 .. code-block:: Python from mobgap.laterality import LrcUllrich lrc = LrcUllrich() lrc.predict( first_gait_sequence_data, ic_list, sampling_rate_hz=sampling_rate_hz ) ic_list = lrc.ic_lr_list_ .. GENERATED FROM PYTHON SOURCE LINES 90-95 Gait Sequence Refinement ------------------------ After detecting the ICs within the gait sequence, we can refine the gait sequence using the ICs. Basically, we restrict the area of the gait sequence to the area between the first and the last IC. This should ensure that the subsequent steps are only getting data that contains detectable gait. .. GENERATED FROM PYTHON SOURCE LINES 95-103 .. code-block:: Python from mobgap.initial_contacts import refine_gs refined_gait_sequence, refined_ic_list = refine_gs(ic_list) refined_gait_sequence_data = first_gait_sequence_data.iloc[ refined_gait_sequence.iloc[0].start : refined_gait_sequence.iloc[0].end ] .. GENERATED FROM PYTHON SOURCE LINES 104-106 Step 3: Cadence Calculation --------------------------- .. GENERATED FROM PYTHON SOURCE LINES 106-118 .. code-block:: Python from mobgap.cadence import CadFromIc cad = CadFromIc() cad.calculate( refined_gait_sequence_data, initial_contacts=refined_ic_list, sampling_rate_hz=sampling_rate_hz, ) cad_per_sec = cad.cadence_per_sec_ cad_per_sec .. raw:: html
cadence_spm
sec_center_samples
50 109.090909
150 109.090909
250 109.090909
350 109.090909
450 96.000000
550 80.000000
650 80.000000
750 77.922078
850 68.965517
950 63.157895
1050 100.000000
1150 100.000000


.. GENERATED FROM PYTHON SOURCE LINES 119-121 Step 4: Stride Length Calculation --------------------------------- .. GENERATED FROM PYTHON SOURCE LINES 121-134 .. code-block:: Python from mobgap.stride_length import SlZijlstra sl = SlZijlstra() sl.calculate( refined_gait_sequence_data, initial_contacts=refined_ic_list, sampling_rate_hz=sampling_rate_hz, **participant_metadata, ) sl_per_sec = sl.stride_length_per_sec_ sl_per_sec .. raw:: html
stride_length_m
sec_center_samples
50 1.164494
150 1.180049
250 1.098622
350 1.031178
450 0.922796
550 0.801989
650 0.514388
750 0.590646
850 0.664410
950 0.305513
1050 0.327321
1150 0.327321


.. GENERATED FROM PYTHON SOURCE LINES 135-144 Step 5: Walking Speed Calculation --------------------------------- Finally, we can calculate the walking speed. This could be done by another sophisticated algorithm that uses the raw data to estimate the walking speed. However, in the Mobilise-D pipeline we opted to base the walking speed calculation on the cadence and stride length to avoid adding a walking speed that would not be coherent with the other results. To allow to modify this in the future and to allow for different walking speed calculation algorithms, we still encapsulate the walking speed calculation in a separate class that takes all the previous results as input. .. GENERATED FROM PYTHON SOURCE LINES 144-158 .. code-block:: Python from mobgap.walking_speed import WsNaive ws = WsNaive() ws.calculate( refined_gait_sequence_data, initial_contacts=refined_ic_list, cadence_per_sec=cad_per_sec, stride_length_per_sec=sl_per_sec, sampling_rate_hz=sampling_rate_hz, **participant_metadata, ) ws_per_sec = ws.walking_speed_per_sec_ ws_per_sec .. raw:: html
walking_speed_mps
sec_center_samples
50 1.058631
150 1.072771
250 0.998748
350 0.937434
450 0.738237
550 0.534659
650 0.342925
750 0.383536
850 0.381845
950 0.160796
1050 0.272768
1150 0.272768


.. GENERATED FROM PYTHON SOURCE LINES 159-168 Step 6: Turn Detection ---------------------- Independent of all other parameters, we detect turns in the gait sequence. This does not influence the calculation of the other parameters, and is only used to gather the ``n_turns`` parameter. Note, that the turning detection is usually done on the non-refined gs. But this shouldn't really matter. .. warning:: The turning algorithm is not evaluated. If you are planning to use detailed turning information, you should perform your own evaluation for your specific use-case. .. GENERATED FROM PYTHON SOURCE LINES 168-175 .. code-block:: Python from mobgap.turning import TdElGohary turn = TdElGohary() turn.detect(first_gait_sequence_data, sampling_rate_hz=sampling_rate_hz) turn_list = turn.turn_list_ turn_list .. raw:: html
start end duration_s angle_deg direction
turn_id
0 392 715 3.23 -71.588625 right
1 727 942 2.15 77.106703 left


.. GENERATED FROM PYTHON SOURCE LINES 176-183 After going through the steps for a single gait sequence, we would then put all the data together to calculate the final results per WB. But let's first put all the processing into an easy-to-read loop. Actual Pipeline --------------- We first define all the algorithms we want to use. .. GENERATED FROM PYTHON SOURCE LINES 183-199 .. code-block:: Python from mobgap.cadence import CadFromIc from mobgap.gait_sequences import GsdIluz from mobgap.initial_contacts import IcdShinImproved, refine_gs from mobgap.laterality import LrcUllrich from mobgap.stride_length import SlZijlstra from mobgap.turning import TdElGohary from mobgap.walking_speed import WsNaive gsd = GsdIluz() icd = IcdShinImproved() lrc = LrcUllrich() cad = CadFromIc() sl = SlZijlstra() speed = WsNaive() turn = TdElGohary() .. GENERATED FROM PYTHON SOURCE LINES 200-204 Then we calculate the gait sequences as before. Note that some of the algorithms might need the participant metadata. Hence, we pass it as keyword argument to all the algorithms. .. GENERATED FROM PYTHON SOURCE LINES 204-207 .. code-block:: Python gsd.detect(imu_data, sampling_rate_hz=sampling_rate_hz, **participant_metadata) gait_sequences = gsd.gs_list_ .. GENERATED FROM PYTHON SOURCE LINES 208-213 Then we use a nested iterator to go through all the gait sequences and process them. To learn more about this iterator, check out the example about the :ref:`Gait Sequence Iterator `. Note, that we use the special ``r`` object to store the results of each step and the ``subregion`` method to elegantly handle the refined gait sequence. .. GENERATED FROM PYTHON SOURCE LINES 213-255 .. code-block:: Python from mobgap.pipeline import GsIterator gs_iterator = GsIterator() for (_, gs_data), r in gs_iterator.iterate(imu_data, gait_sequences): icd = icd.clone().detect( gs_data, sampling_rate_hz=sampling_rate_hz, **participant_metadata ) lrc = lrc.clone().predict( gs_data, icd.ic_list_, sampling_rate_hz=sampling_rate_hz ) r.ic_list = lrc.ic_lr_list_ turn = turn.clone().detect(gs_data, sampling_rate_hz=sampling_rate_hz) r.turn_list = turn.turn_list_ refined_gs, refined_ic_list = refine_gs(r.ic_list) with gs_iterator.subregion(refined_gs) as ((_, refined_gs_data), rr): cad = cad.clone().calculate( refined_gs_data, initial_contacts=refined_ic_list, sampling_rate_hz=sampling_rate_hz, **participant_metadata, ) rr.cadence_per_sec = cad.cadence_per_sec_ sl = sl.clone().calculate( refined_gs_data, initial_contacts=refined_ic_list, sampling_rate_hz=sampling_rate_hz, **participant_metadata, ) rr.stride_length_per_sec = sl.stride_length_per_sec_ speed = speed.clone().calculate( refined_gs_data, initial_contacts=refined_ic_list, cadence_per_sec=cad.cadence_per_sec_, stride_length_per_sec=sl.stride_length_per_sec_, sampling_rate_hz=sampling_rate_hz, **participant_metadata, ) rr.walking_speed_per_sec = speed.walking_speed_per_sec_ .. GENERATED FROM PYTHON SOURCE LINES 256-257 Now we can access all accumulated and offset-corrected results from the iterator. .. GENERATED FROM PYTHON SOURCE LINES 257-261 .. code-block:: Python results = gs_iterator.results_ results.ic_list .. raw:: html
ic lr_label
gs_id step_id
0 0 986 right
1 1058 left
2 1116 right
3 1171 left
4 1226 right
... ... ... ...
6 10 22094 left
11 22219 left
12 22313 right
13 22348 left
14 22436 left

136 rows × 2 columns



.. GENERATED FROM PYTHON SOURCE LINES 262-267 We combine all per-sec results into one. Note, that we remove the ``r_gs_id`` index, as we don't need it anymore and each normal ``gs`` is mapped to a single refined ``gs`` anyway. In case we would have multiple refined ``gs`` per normal ``gs``, we might need to keep the ``r_gs_id`` index around. .. GENERATED FROM PYTHON SOURCE LINES 267-277 .. code-block:: Python combined_results = pd.concat( [ results.cadence_per_sec, results.stride_length_per_sec, results.walking_speed_per_sec, ], axis=1, ).reset_index("r_gs_id", drop=True) combined_results .. raw:: html
cadence_spm stride_length_m walking_speed_mps
gs_id sec_center_samples
0 1036 109.090909 1.164494 1.058631
1136 109.090909 1.180049 1.072771
1236 109.090909 1.098622 0.998748
1336 109.090909 1.031178 0.937434
1436 96.000000 0.922796 0.738237
... ... ... ... ...
6 22016 63.829787 0.974711 0.518463
22116 63.829787 1.045141 0.555926
22216 63.829787 1.076485 0.572598
22316 68.181818 0.611750 0.347585
22416 68.181818 0.783434 0.445133

94 rows × 3 columns



.. GENERATED FROM PYTHON SOURCE LINES 278-282 Using the combined results, we want to define walking bouts. As walking bouts in the context of Mobilise-D are defined based on strides, we need to turn the ICs into strides and the per-second values into per-stride values by using interpolation. We also calculate the stride duration here. .. GENERATED FROM PYTHON SOURCE LINES 282-293 .. code-block:: Python from mobgap.laterality import strides_list_from_ic_lr_list stride_list = ( results.ic_list.groupby("gs_id", group_keys=False) .apply(strides_list_from_ic_lr_list) .assign( stride_duration_s=lambda df_: (df_.end - df_.start) / sampling_rate_hz ) ) stride_list .. raw:: html
start end lr_label stride_duration_s
gs_id s_id
0 0 986 1116 right 1.30
1 1058 1171 left 1.13
2 1116 1226 right 1.10
3 1171 1281 left 1.10
4 1226 1341 right 1.15
... ... ... ... ... ...
6 8 21920 22313 right 3.93
9 22017 22094 left 0.77
10 22094 22219 left 1.25
11 22219 22348 left 1.29
13 22348 22436 left 0.88

122 rows × 4 columns



.. GENERATED FROM PYTHON SOURCE LINES 294-300 This initial stride list is completely unfiltered, and might contain very long strides, in areas where initial contacts were not detected, or the participant was not walking for a short moment. The stride list will be filtered later as part of the WB assembly. For now, we are using linear interpolation to map the per-second cadence values to per-stride values and derive approximated stride parameters. .. GENERATED FROM PYTHON SOURCE LINES 300-310 .. code-block:: Python from mobgap.utils.df_operations import create_multi_groupby stride_list_with_approx_paras = create_multi_groupby( stride_list, combined_results, "gs_id", group_keys=False, ).apply(naive_sec_paras_to_regions, sampling_rate_hz=sampling_rate_hz) stride_list_with_approx_paras .. raw:: html
start end lr_label stride_duration_s cadence_spm stride_length_m walking_speed_mps
gs_id s_id
0 0 986 1116 right 1.30 109.090909 1.168084 1.061894
1 1058 1171 left 1.13 109.090909 1.176194 1.069268
2 1116 1226 right 1.10 109.090909 1.150439 1.045854
3 1171 1281 left 1.10 109.090909 1.109726 1.008842
4 1226 1341 right 1.15 109.090909 1.066366 0.969424
... ... ... ... ... ... ... ... ...
6 8 21920 22313 right 3.93 64.119192 0.974239 0.519003
9 22017 22094 left 0.77 63.829787 1.000322 0.532086
10 22094 22219 left 1.25 63.829787 1.058431 0.562995
11 22219 22348 left 1.29 66.596195 0.781072 0.429567
13 22348 22436 left 0.88 68.181818 0.748316 0.425180

122 rows × 7 columns



.. GENERATED FROM PYTHON SOURCE LINES 311-314 Now the final strides are regrouped into walking bouts. For this we ignore which gait sequence the strides belong to, hence we remove the ``gs_id`` from the index, but keep it around as column for debugging. .. GENERATED FROM PYTHON SOURCE LINES 314-329 .. code-block:: Python from mobgap.wba import StrideSelection, WbAssembly flat_index = pd.Index( [ "_".join(str(e) for e in s_id) for s_id in stride_list_with_approx_paras.index ], name="s_id", ) stride_list_with_approx_paras = ( stride_list_with_approx_paras.reset_index("gs_id") .rename(columns={"gs_id": "original_gs_id"}) .set_index(flat_index) ) .. GENERATED FROM PYTHON SOURCE LINES 330-332 Then we apply the stride selection (note that we have additional rules in case the stride length is available) and then group the remaining strides into walking bouts. .. GENERATED FROM PYTHON SOURCE LINES 332-344 .. code-block:: Python ss = StrideSelection().filter( stride_list_with_approx_paras, sampling_rate_hz=sampling_rate_hz ) wba = WbAssembly().assemble( ss.filtered_stride_list_, raw_initial_contacts=results.ic_list, sampling_rate_hz=sampling_rate_hz, ) final_strides = wba.annotated_stride_list_ final_strides .. raw:: html
original_gs_id start end lr_label stride_duration_s cadence_spm stride_length_m walking_speed_mps
wb_id s_id
0 0_0 0 986 1116 right 1.30 109.090909 1.168084 1.061894
0_1 0 1058 1171 left 1.13 109.090909 1.176194 1.069268
0_2 0 1116 1226 right 1.10 109.090909 1.150439 1.045854
0_3 0 1171 1281 left 1.10 109.090909 1.109726 1.008842
0_4 0 1226 1341 right 1.15 109.090909 1.066366 0.969424
... ... ... ... ... ... ... ... ... ...
4 6_7 6 21827 21920 right 0.93 62.971346 0.889741 0.465905
6_9 6 22017 22094 left 0.77 63.829787 1.000322 0.532086
6_10 6 22094 22219 left 1.25 63.829787 1.058431 0.562995
6_11 6 22219 22348 left 1.29 66.596195 0.781072 0.429567
6_13 6 22348 22436 left 0.88 68.181818 0.748316 0.425180

120 rows × 8 columns



.. GENERATED FROM PYTHON SOURCE LINES 345-346 We also have meta information about the WBs available. .. GENERATED FROM PYTHON SOURCE LINES 346-349 .. code-block:: Python per_wb_params = wba.wb_meta_parameters_ per_wb_params.drop(columns="rule_obj").T .. raw:: html
wb_id 0 1 2 3 4
start 986 4668 9707 11304 19996
end 2091 6049 10794 14796 22436
n_strides 15 17 13 47 28
rule_name max_break max_break max_break max_break max_break
duration_s 11.05 13.81 10.87 34.92 24.4
n_raw_initial_contacts 17 19 15 52 33


.. GENERATED FROM PYTHON SOURCE LINES 350-351 We extend them further with the per-stride parameters. .. GENERATED FROM PYTHON SOURCE LINES 351-369 .. code-block:: Python params_to_aggregate = [ "stride_duration_s", "cadence_spm", "stride_length_m", "walking_speed_mps", ] per_wb_params = pd.concat( [ per_wb_params, final_strides.reindex(columns=params_to_aggregate) .groupby(["wb_id"]) .mean(), ], axis=1, ) per_wb_params.drop(columns="rule_obj").T .. raw:: html
wb_id 0 1 2 3 4
start 986 4668 9707 11304 19996
end 2091 6049 10794 14796 22436
n_strides 15 17 13 47 28
rule_name max_break max_break max_break max_break max_break
duration_s 11.05 13.81 10.87 34.92 24.4
n_raw_initial_contacts 17 19 15 52 33
stride_duration_s 1.211333 1.462353 1.424615 1.235106 1.292143
cadence_spm 93.902776 81.553515 82.836029 97.107214 87.62698
stride_length_m 0.814055 0.81388 0.662401 0.736345 0.83613
walking_speed_mps 0.667326 0.535375 0.46741 0.59769 0.601725


.. GENERATED FROM PYTHON SOURCE LINES 370-371 For each WB we can then apply thresholds to check if the calculated parameters are within the expected range. .. GENERATED FROM PYTHON SOURCE LINES 371-386 .. code-block:: Python from mobgap.aggregation import apply_thresholds, get_mobilised_dmo_thresholds thresholds = get_mobilised_dmo_thresholds() per_wb_params_mask = apply_thresholds( per_wb_params, thresholds, cohort=long_trial.participant_metadata["cohort"], height_m=long_trial.participant_metadata["height_m"], measurement_condition=long_trial.recording_metadata[ "measurement_condition" ], ) per_wb_params_mask.T .. raw:: html
wb_id 0 1 2 3 4
start NaN NaN NaN NaN NaN
end NaN NaN NaN NaN NaN
n_strides NaN NaN NaN NaN NaN
rule_name NaN NaN NaN NaN NaN
rule_obj NaN NaN NaN NaN NaN
duration_s NaN NaN NaN NaN NaN
n_raw_initial_contacts NaN NaN NaN NaN NaN
stride_duration_s True True True True True
cadence_spm True True True True True
stride_length_m True True True True True
walking_speed_mps True True True True True


.. GENERATED FROM PYTHON SOURCE LINES 387-395 We can see that we either get NaN (for parameters that are not checked) or True/False values for each parameter. This output together with the per-WB parameters would then normally be used in some aggregation step to calculate single values per participant, day, or other grouping criteria. Depending on the use-case, this aggregation can be performed withing the "per-recording" pipeline or as a separate step after processing all recordings. Here, we perform it per recording and calculate a single values from all the WBs. .. GENERATED FROM PYTHON SOURCE LINES 395-406 .. code-block:: Python from mobgap.aggregation import MobilisedAggregator agg = MobilisedAggregator( **MobilisedAggregator.PredefinedParameters.single_recording ) agg_results = agg.aggregate( per_wb_params, wb_dmos_mask=per_wb_params_mask ).aggregated_data_ agg_results.T .. raw:: html
all_wbs
wb_all__count 5
total_walking_duration_min 1.584167
wb_all__n_raw_initial_contacts__sum 136
wb_all__duration_s__avg 13.81
wb_all__duration_s__p90 30.712
wb_all__duration_s__var 0.550987
wb_all__cadence_spm__avg 88.605303
wb_all__stride_duration_s__avg 1.32511
wb_all__cadence_spm__var 0.076611
wb_all__stride_duration_s__var 0.085103
wb_10_30__count 4
wb_10_30__walking_speed_mps__avg 0.567959
wb_10_30__stride_length_m__avg 0.781617
wb_10__count 5
wb_10__walking_speed_mps__p90 0.641085
wb_30__count 1
wb_30__walking_speed_mps__avg 0.59769
wb_30__stride_length_m__avg 0.736345
wb_30__cadence_spm__avg 97.107214
wb_30__stride_duration_s__avg 1.235106
wb_30__walking_speed_mps__p90 0.59769
wb_30__cadence_spm__p90 97.107214
wb_30__walking_speed_mps__var NaN
wb_30__stride_length_m__var NaN
wb_60__count 0


.. GENERATED FROM PYTHON SOURCE LINES 407-412 Running as a single pipeline ---------------------------- The steps that are shown above, are exactly the steps that are performed in the Mobilise-D pipeline. Hence, we can also use the pre-built pipeline to perform the same steps. This is shown below. .. GENERATED FROM PYTHON SOURCE LINES 412-430 .. code-block:: Python from mobgap.pipeline import GenericMobilisedPipeline pipeline = GenericMobilisedPipeline( gait_sequence_detection=gsd, initial_contact_detection=icd, laterality_classification=lrc, cadence_calculation=cad, stride_length_calculation=sl, turn_detection=turn, walking_speed_calculation=ws, stride_selection=ss, wba=wba, dmo_thresholds=thresholds, dmo_aggregation=agg, ) pipeline.safe_run(long_trial) .. rst-class:: sphx-glr-script-out .. code-block:: none GenericMobilisedPipeline(cadence_calculation=CadFromIc(max_interpolation_gap_s=3, step_time_smoothing=HampelFilter(half_window_size=2, n_sigmas=3.0)), dmo_aggregation=MobilisedAggregator(groupby=None, unique_wb_id_column='wb_id', use_original_names=False), dmo_thresholds=condition free_living ... global threshold_type min max ... min max dmo cohort ... cadence_spm CHF 40.594770 167.942930 ... 40.000000 172.900 COPD 38.880484 151.558718 ... 40.000000 172.900 HA 35.751898 156.946955 ... 40.000000 172.900 MS 38.443211 155.394496 ... 40.000000 172.900 PD 40.957969 142.121947 ... 40.000000 172.900 PFF 42.191719 157.613665 ... 40.000000 172.900 walking_speed_mps CHF 0.112478 1.757103 ... 0.081515 2.220 COPD 0.090731 1.641773 ... 0.081515 2.220 HA 0.097413 1.965728 ... 0.081515 2.220 MS 0.085918 1.920262 ... 0.081515 2.220 PD 0.081515 1.735348 ... 0.081515 2.220 PFF 0.104547 1.553186 ... 0.081515 2.220 stride_length_m CHF 0.185308 2.166646 ... 0.150523 2.190 COPD 0.176403 1.711645 ... 0.150523 2.190 HA 0.155126 2.024694 ... 0.150523 2.190 MS 0.191099 1.940537 ... 0.150523 2.190 PD 0.150523 1.982926 ... 0.150523 2.190 PFF 0.206787 1.697251 ... 0.150523 2.190 stride_duration_s CHF 0.702000 3.030857 ... 0.460000 3.000 COPD 0.770000 3.000000 ... 0.460000 3.000 HA 0.735435 3.254400 ... 0.460000 3.000 MS 0.775597 3.057750 ... 0.460000 3.000 PD 0.836253 2.928000 ... 0.460000 3.000 PFF 0.744000 2.769000 ... 0.460000 3.000 step_duration_s CHF 0.376000 1.504500 ... 0.140000 2.124 COPD 0.390400 1.788000 ... 0.140000 2.124 HA 0.367972 1.730400 ... 0.140000 2.124 MS 0.388084 1.905000 ... 0.140000 2.124 PD 0.417216 1.605600 ... 0.140000 2.124 PFF 0.371429 2.124000 ... 0.140000 2.124 [30 rows x 8 columns], gait_sequence_detection=GsdIluz(acc_v_standing_threshold=4.903325, allowed_acc_v_change_per_window=0.15, allowed_steps_per_s=(0.6666666666666666, 3), mean_activity_threshold=-0.980665, min_gsd_duration_s=5, pre_filter=FirFilter(cutoff_freq_hz=(0.5, 3), filter_type='bandpass', order=100, window='hamming', zero_phase=True), sin_template_freq_hz=2, std_activity_threshold=0.0980665, step_detection_thresholds=(0.0392266, 0.04903325), use_original_peak_detection=False, window_length_s=3, window_overlap=0.5), initial_contact_detection=IcdShinImproved(axis='norm'), laterality_classification=LrcUllrich(clf_pipe=Pipeline(steps=[('scaler', MinMaxScaler()), ('clf', SVC(C=1, kernel='linear'))]), smoothing_filter=ButterworthFilter(cutoff_freq_hz=(0.5, 2), filter_type='bandpass', order=4, zero_phase=True)), recommended_cohorts=None, stride_length_calculation=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)), stride_selection=StrideSelection(incompatible_rules='warn', rules=[('stride_duration_thres', IntervalDurationCriteria(inclusive=(False, True), max_duration_s=3.0, min_duration_s=0.2)), ('stride_length_thres', IntervalParameterCriteria(inclusive=(False, True), lower_threshold=0.15, parameter='stride_length_m', upper_threshold=None))]), turn_detection=TdElGohary(allowed_turn_angle_deg=(45, inf), allowed_turn_duration_s=(0.5, 10), lower_threshold_velocity_dps=5, min_gap_between_turns_s=0.05, min_peak_angle_velocity_dps=15, orientation_estimation=None, smoothing_filter=ButterworthFilter(cutoff_freq_hz=0.5, filter_type='lowpass', order=4, zero_phase=True)), walking_speed_calculation=WsNaive(), wba=WbAssembly(rules=[('min_strides', NStridesCriteria(min_strides=4, min_strides_left=3, min_strides_right=3)), ('max_break', MaxBreakCriteria(consider_end_as_break=True, max_break_s=3, remove_last_ic=False))])) .. GENERATED FROM PYTHON SOURCE LINES 431-435 The results are stored in the pipeline object. And basically all the individual results that are shown above are also available in the pipeline object. For example the per stride parameters: .. GENERATED FROM PYTHON SOURCE LINES 435-437 .. code-block:: Python pipeline.raw_per_stride_parameters_ .. raw:: html
start end lr_label stride_duration_s cadence_spm stride_length_m walking_speed_mps
gs_id s_id
0 0 986 1116 right 1.30 109.090909 1.168084 1.061894
1 1058 1171 left 1.13 109.090909 1.176194 1.069268
2 1116 1226 right 1.10 109.090909 1.150439 1.045854
3 1171 1281 left 1.10 109.090909 1.109726 1.008842
4 1226 1341 right 1.15 109.090909 1.066366 0.969424
... ... ... ... ... ... ... ... ...
6 8 21920 22313 right 3.93 64.119192 0.974239 0.519003
9 22017 22094 left 0.77 63.829787 1.000322 0.532086
10 22094 22219 left 1.25 63.829787 1.058431 0.562995
11 22219 22348 left 1.29 66.596195 0.781072 0.429567
13 22348 22436 left 0.88 68.181818 0.748316 0.425180

122 rows × 7 columns



.. GENERATED FROM PYTHON SOURCE LINES 438-439 The per-wb parameters: .. GENERATED FROM PYTHON SOURCE LINES 439-441 .. code-block:: Python pipeline.per_wb_parameters_ .. raw:: html
start end n_strides rule_name rule_obj duration_s n_raw_initial_contacts stride_duration_s cadence_spm stride_length_m walking_speed_mps
wb_id
0 986 2091 15 max_break MaxBreakCriteria(consider_end_as_break=True, m... 11.05 17 1.211333 93.902776 0.814055 0.667326
1 4668 6049 17 max_break MaxBreakCriteria(consider_end_as_break=True, m... 13.81 19 1.462353 81.553515 0.813880 0.535375
2 9707 10794 13 max_break MaxBreakCriteria(consider_end_as_break=True, m... 10.87 15 1.424615 82.836029 0.662401 0.467410
3 11304 14796 47 max_break MaxBreakCriteria(consider_end_as_break=True, m... 34.92 52 1.235106 97.107214 0.736345 0.597690
4 19996 22436 28 max_break MaxBreakCriteria(consider_end_as_break=True, m... 24.40 33 1.292143 87.626980 0.836130 0.601725


.. GENERATED FROM PYTHON SOURCE LINES 442-443 And the aggregated parameters: .. GENERATED FROM PYTHON SOURCE LINES 443-444 .. code-block:: Python pipeline.aggregated_parameters_ .. raw:: html
wb_all__count total_walking_duration_min wb_all__n_raw_initial_contacts__sum wb_all__duration_s__avg wb_all__duration_s__p90 wb_all__duration_s__var wb_all__cadence_spm__avg wb_all__stride_duration_s__avg wb_all__cadence_spm__var wb_all__stride_duration_s__var wb_10_30__count wb_10_30__walking_speed_mps__avg wb_10_30__stride_length_m__avg wb_10__count wb_10__walking_speed_mps__p90 wb_30__count wb_30__walking_speed_mps__avg wb_30__stride_length_m__avg wb_30__cadence_spm__avg wb_30__stride_duration_s__avg wb_30__walking_speed_mps__p90 wb_30__cadence_spm__p90 wb_30__walking_speed_mps__var wb_30__stride_length_m__var wb_60__count
all_wbs 5 1.584167 136 13.81 30.712 0.550987 88.605303 1.32511 0.076611 0.085103 4 0.567959 0.781617 5 0.641085 1 0.59769 0.736345 97.107214 1.235106 0.59769 97.107214 NaN NaN 0


.. rst-class:: sphx-glr-timing **Total running time of the script:** (0 minutes 6.823 seconds) **Estimated memory usage:** 86 MB .. _sphx_glr_download_auto_examples_pipeline__02_step_by_step_mobilised_pipeline.py: .. only:: html .. container:: sphx-glr-footer sphx-glr-footer-example .. container:: sphx-glr-download sphx-glr-download-jupyter :download:`Download Jupyter notebook: _02_step_by_step_mobilised_pipeline.ipynb <_02_step_by_step_mobilised_pipeline.ipynb>` .. container:: sphx-glr-download sphx-glr-download-python :download:`Download Python source code: _02_step_by_step_mobilised_pipeline.py <_02_step_by_step_mobilised_pipeline.py>` .. container:: sphx-glr-download sphx-glr-download-zip :download:`Download zipped: _02_step_by_step_mobilised_pipeline.zip <_02_step_by_step_mobilised_pipeline.zip>` .. only:: html .. rst-class:: sphx-glr-signature `Gallery generated by Sphinx-Gallery `_