.. DO NOT EDIT. .. THIS FILE WAS AUTOMATICALLY GENERATED BY SPHINX-GALLERY. .. TO MAKE CHANGES, EDIT THE SOURCE PYTHON FILE: .. "auto_examples/pipeline/_03_preconfigured_mobilised_pipelines.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__03_preconfigured_mobilised_pipelines.py: Preconfigured Mobilised Pipelines ================================= As part of the Mobilise-D project two separate pipelines have been developed depending on the patient characteristics. The first pipeline :class:`~mobgab.pipeline.MobilisedPipelineHealthy` (P1 in [1]_) is designed for people that likely still have a somewhat normal gait pattern. In Mobilise-D, this pipeline is used for healthy controls and patients with "COPD" and "CHF". The second pipeline :class:`~mobgab.pipeline.MobilisedPipelineImpaired` (P2 in [1]_) is designed for patients with likely significantly impaired gait patterns. In Mobilise-D, this pipeline is used for patients with "PD", "PFF" and "MS". In this example we will show how to use these preconfigured pipelines. If you want to understand the details of the pipelines, please refer to the `step-by-step example `_. .. [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 23-27 Data ---- For this example, we will use the provided example data. It contains data from Lab tests from MS patients and healthy controls. .. GENERATED FROM PYTHON SOURCE LINES 27-32 .. code-block:: Python from mobgap.data import LabExampleDataset data_ha = LabExampleDataset().get_subset(cohort="HA") data_ha .. raw:: html

LabExampleDataset [6 groups/rows]

cohort participant_id time_measure test trial
0 HA 001 TimeMeasure1 Test5 Trial1
1 HA 001 TimeMeasure1 Test5 Trial2
2 HA 001 TimeMeasure1 Test11 Trial1
3 HA 002 TimeMeasure1 Test5 Trial1
4 HA 002 TimeMeasure1 Test5 Trial2
5 HA 002 TimeMeasure1 Test11 Trial1


.. GENERATED FROM PYTHON SOURCE LINES 33-36 .. code-block:: Python data_ms = LabExampleDataset().get_subset(cohort="MS") data_ms .. raw:: html

LabExampleDataset [3 groups/rows]

cohort participant_id time_measure test trial
0 MS 001 TimeMeasure1 Test5 Trial1
1 MS 001 TimeMeasure1 Test5 Trial2
2 MS 001 TimeMeasure1 Test11 Trial1


.. GENERATED FROM PYTHON SOURCE LINES 37-39 Mobilised Pipeline Healthy -------------------------- .. GENERATED FROM PYTHON SOURCE LINES 39-43 .. code-block:: Python from mobgap.pipeline import MobilisedPipelineHealthy, MobilisedPipelineUniversal pipeline_ha = MobilisedPipelineHealthy() .. GENERATED FROM PYTHON SOURCE LINES 44-45 We just apply the pipeline to the first long test in the data. .. GENERATED FROM PYTHON SOURCE LINES 45-49 .. code-block:: Python long_test_ha = data_ha.get_subset(test="Test11")[0] pipeline_ha = pipeline_ha.safe_run(long_test_ha) .. GENERATED FROM PYTHON SOURCE LINES 50-58 Now we can access the results. Note, that the pipelines contain a large number of results. Not all of them are relevant for every use case. We only show the main outputs here: The main output are the aggregated parameters. By default, this is just a single output for each recording. It describes the overall statistics and aggregated parameters over all WBs. .. GENERATED FROM PYTHON SOURCE LINES 58-60 .. code-block:: Python pipeline_ha.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 6 0.644333 59 5.97 9.325 0.423421 90.855556 1.294622 0.085824 0.212845 1 0.559393 0.808942 1 0.559393 0 NaN NaN NaN NaN NaN NaN NaN NaN 0


.. GENERATED FROM PYTHON SOURCE LINES 61-63 On level below, we have the WB parameters. This is a DataFrame with the parameters per WB. .. GENERATED FROM PYTHON SOURCE LINES 63-65 .. code-block:: Python pipeline_ha.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 630 1112 7 max_break MaxBreakCriteria(consider_end_as_break=True, m... 4.82 9 1.180000 102.691989 1.091216 0.937171
1 4488 5198 7 max_break MaxBreakCriteria(consider_end_as_break=True, m... 7.10 9 1.604286 91.361289 1.087672 0.826486
2 7848 8935 13 max_break MaxBreakCriteria(consider_end_as_break=True, m... 10.87 15 1.474615 78.868436 0.808942 0.559393
3 9390 10168 10 max_break MaxBreakCriteria(consider_end_as_break=True, m... 7.78 12 1.353000 92.854194 0.886643 0.672637
4 11140 11465 4 max_break MaxBreakCriteria(consider_end_as_break=True, m... 3.25 6 0.812500 87.109927 0.839166 0.640479
5 13118 13602 6 max_break MaxBreakCriteria(consider_end_as_break=True, m... 4.84 8 1.343333 92.247498 1.042166 0.833501


.. GENERATED FROM PYTHON SOURCE LINES 66-68 Even more granular are the stride level parameters. They contain only the strides that are also part of a valid WB. .. GENERATED FROM PYTHON SOURCE LINES 68-70 .. code-block:: Python pipeline_ha.per_stride_parameters_ .. 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 630 760 left 1.30 105.263158 1.237825 1.085811
0_1 0 698 815 right 1.17 105.263158 1.247830 1.094588
0_2 0 760 872 left 1.12 105.612483 1.214743 1.068913
0_3 0 815 925 right 1.10 106.067663 1.164436 1.029147
0_4 0 872 985 left 1.13 100.861834 1.085603 0.915503
0_5 0 925 1042 right 1.17 96.368564 0.974691 0.781070
0_6 0 985 1112 left 1.27 99.407066 0.713383 0.585167
1 1_0 1 4488 4638 left 1.50 85.764810 1.280748 0.899606
1_1 1 4552 4755 right 2.03 95.303530 1.194072 0.938281
1_2 1 4638 4862 left 2.24 92.536877 1.121114 0.867656
1_3 1 4755 4812 right 0.57 89.437482 1.138105 0.854066
1_4 1 4812 5040 right 2.28 88.775075 0.908678 0.671618
1_5 1 4862 4965 left 1.03 89.293040 0.793105 0.588134
1_7 1 5040 5198 right 1.58 98.418209 1.177883 0.966043
2 2_0 2 7848 8095 left 2.47 67.134472 0.705201 0.394626
2_1 2 7985 8228 right 2.43 83.460045 0.768262 0.534401
2_2 2 8095 8165 left 0.70 88.021059 0.789061 0.576721
2_3 2 8165 8280 left 1.15 104.014785 0.800068 0.690972
2_4 2 8228 8335 right 1.07 99.824961 0.902815 0.749123
2_5 2 8280 8398 left 1.18 95.795841 1.006930 0.801848
2_6 2 8335 8460 right 1.25 91.912397 1.078566 0.825589
2_7 2 8398 8540 left 1.42 85.391470 1.070109 0.762411
2_8 2 8460 8608 right 1.48 80.544024 1.073914 0.720547
2_9 2 8540 8680 left 1.40 72.027129 0.993106 0.617321
2_10 2 8608 8815 right 2.07 55.479278 0.590501 0.293911
2_11 2 8680 8768 left 0.88 49.052632 0.539906 0.217885
2_12 2 8768 8935 left 1.67 52.631579 0.197808 0.086758
3 3_0 3 9390 9592 left 2.02 90.915962 0.884044 0.669797
3_1 3 9530 9725 right 1.95 90.785057 1.125851 0.851740
3_2 3 9592 9658 left 0.66 91.603053 1.166823 0.890705
3_3 3 9658 9790 left 1.32 89.051721 1.161388 0.861900
3_4 3 9725 9855 right 1.30 87.283115 1.075365 0.782846
3_5 3 9790 9932 left 1.42 85.106678 0.958814 0.680796
3_6 3 9855 10002 right 1.47 85.214116 0.883336 0.623014
3_7 3 9932 10105 left 1.73 98.305392 0.657076 0.524015
3_8 3 10002 10062 right 0.60 107.142857 0.580316 0.518139
3_9 3 10062 10168 right 1.06 103.133994 0.373418 0.323415
4 4_1 4 11140 11218 right 0.78 80.000000 0.977717 0.651811
4_2 4 11218 11295 right 0.77 84.675325 0.900354 0.634645
4_3 4 11295 11360 right 0.65 96.654457 0.800686 0.634980
4_4 4 11360 11465 right 1.05 NaN 0.677908 NaN
5 5_0 5 13118 13295 left 1.77 95.569545 1.093563 0.871466
5_1 5 13170 13232 right 0.62 95.410138 1.021363 0.812453
5_2 5 13232 13355 right 1.23 94.060430 1.219165 0.958232
5_3 5 13295 13420 left 1.25 90.620860 1.097766 0.831089
5_4 5 13355 13492 right 1.37 85.576517 0.970061 0.694266
5_5 5 13420 13602 left 1.82 NaN 0.851080 NaN


.. GENERATED FROM PYTHON SOURCE LINES 71-72 For other results, see the documentation of the pipeline class itself. .. GENERATED FROM PYTHON SOURCE LINES 74-76 Mobilised Pipeline Impaired --------------------------- .. GENERATED FROM PYTHON SOURCE LINES 76-80 .. code-block:: Python from mobgap.pipeline import MobilisedPipelineImpaired pipeline_ms = MobilisedPipelineImpaired() .. GENERATED FROM PYTHON SOURCE LINES 81-82 We just apply the pipeline to the first long test in the data. .. GENERATED FROM PYTHON SOURCE LINES 82-86 .. code-block:: Python long_test_ms = data_ms.get_subset(test="Test11")[0] pipeline_ms = pipeline_ms.safe_run(long_test_ms) .. GENERATED FROM PYTHON SOURCE LINES 87-88 Like before we can access the results. .. GENERATED FROM PYTHON SOURCE LINES 88-90 .. code-block:: Python pipeline_ms.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.061167 98 9.15 19.672 0.48378 93.264236 1.188077 0.079881 0.078924 2 0.690202 0.89055 2 0.731612 0 NaN NaN NaN NaN NaN NaN NaN NaN 0


.. GENERATED FROM PYTHON SOURCE LINES 91-93 .. code-block:: Python pipeline_ms.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 979 1835 12 max_break MaxBreakCriteria(consider_end_as_break=True, m... 8.56 14 1.305000 92.900366 0.923630 0.746727
1 5230 5982 8 max_break MaxBreakCriteria(consider_end_as_break=True, m... 7.52 11 1.175000 87.808553 0.914782 0.650693
2 9715 10630 11 max_break MaxBreakCriteria(consider_end_as_break=True, m... 9.15 14 1.074545 100.575934 0.678129 0.571437
3 12994 14690 27 max_break MaxBreakCriteria(consider_end_as_break=True, m... 16.96 29 1.128148 100.810922 0.879267 0.741964
4 20287 22435 26 max_break MaxBreakCriteria(consider_end_as_break=True, m... 21.48 30 1.257692 84.225406 0.901833 0.638440


.. GENERATED FROM PYTHON SOURCE LINES 94-96 .. code-block:: Python pipeline_ms.per_stride_parameters_ .. 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 979 1117 right 1.38 105.780756 1.166079 1.027968
0_1 0 1062 1172 left 1.10 106.852358 1.177377 1.048420
0_2 0 1117 1227 right 1.10 107.564058 1.143444 1.024778
0_3 0 1172 1282 left 1.10 107.944130 1.100256 0.989706
0_4 0 1227 1339 right 1.12 106.093671 1.079993 0.955065
... ... ... ... ... ... ... ... ... ...
4 4_23 4 21985 22130 right 1.45 58.803137 0.954794 0.467671
4_24 4 22030 22090 left 0.60 58.339806 0.971503 0.472266
4_25 4 22090 22227 left 1.37 65.532078 0.874395 0.473468
4_27 4 22227 22353 left 1.26 91.781177 0.786764 0.601751
4_28 4 22353 22435 left 0.82 NaN 0.786764 NaN

84 rows × 8 columns



.. GENERATED FROM PYTHON SOURCE LINES 97-107 That's it. As you can see, it is super simple to run the preconfigured pipelines on your data, if they are structured as a valid gait dataset. However, when running a larger study, you might want to process all data at once. Then it become "inconvenient" to run the pipeline for each recording separately manually. Luckily, it is relatively easy to implement a loop that runs the pipeline for each recording. We can even use :class:`~mobgap.pipeline.MobilisedPipelineUniversal` to automatically process all MS participants with the impaired pipeline and all HA participants with the healthy pipeline. .. GENERATED FROM PYTHON SOURCE LINES 107-115 .. code-block:: Python meta_pipeline = MobilisedPipelineUniversal( pipelines=[ ("healthy", MobilisedPipelineHealthy()), ("impaired", MobilisedPipelineImpaired()), ] ) .. GENERATED FROM PYTHON SOURCE LINES 116-118 The meta-pipeline uses the ``recommended_cohorts`` parameter of the respective pipeline to determine which pipeline to use. .. GENERATED FROM PYTHON SOURCE LINES 118-120 .. code-block:: Python MobilisedPipelineHealthy().recommended_cohorts .. rst-class:: sphx-glr-script-out .. code-block:: none ('HA', 'COPD', 'CHF') .. GENERATED FROM PYTHON SOURCE LINES 121-123 .. code-block:: Python MobilisedPipelineImpaired().recommended_cohorts .. rst-class:: sphx-glr-script-out .. code-block:: none ('PD', 'MS', 'PFF') .. GENERATED FROM PYTHON SOURCE LINES 124-130 So we can simply loop over all the data and run the meta-pipeline. We add a little bit of logic to deal with trials that for which we might not detect a valid WB. Then we aggregate the results. For the ``aggreate_parameters`` we modify the index, so that we have rows with NaNs for the trials that did not have any valid WBs. .. GENERATED FROM PYTHON SOURCE LINES 130-151 .. code-block:: Python import pandas as pd from tqdm.auto import tqdm per_wb_paras = {} aggregated_paras = {} for trial in tqdm(LabExampleDataset()): pipe = meta_pipeline.clone().safe_run(trial) if not (per_wb := pipe.per_wb_parameters_).empty: per_wb_paras[trial.group_label] = per_wb if not (agg := pipe.aggregated_parameters_).empty: aggregated_paras[trial.group_label] = agg per_wb_paras = pd.concat(per_wb_paras) aggregated_paras = ( pd.concat(aggregated_paras) .reset_index(-1, drop=True) .rename_axis(LabExampleDataset().index.columns) .reindex(pd.MultiIndex.from_tuples(LabExampleDataset().group_labels)) ) .. rst-class:: sphx-glr-script-out .. code-block:: none 0%| | 0/9 [00:00
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
HA 001 TimeMeasure1 Test5 Trial1 0 498 1115 9 max_break MaxBreakCriteria(consider_end_as_break=True, m... 6.17 11 1.083333 98.037623 1.119209 0.916171
Trial2 0 288 978 10 max_break MaxBreakCriteria(consider_end_as_break=True, m... 6.90 12 1.235000 98.346463 1.133209 0.942443
Test11 Trial1 0 630 1112 7 max_break MaxBreakCriteria(consider_end_as_break=True, m... 4.82 9 1.180000 102.691989 1.091216 0.937171
1 4488 5198 7 max_break MaxBreakCriteria(consider_end_as_break=True, m... 7.10 9 1.604286 91.361289 1.087672 0.826486
2 7848 8935 13 max_break MaxBreakCriteria(consider_end_as_break=True, m... 10.87 15 1.474615 78.868436 0.808942 0.559393
3 9390 10168 10 max_break MaxBreakCriteria(consider_end_as_break=True, m... 7.78 12 1.353000 92.854194 0.886643 0.672637
4 11140 11465 4 max_break MaxBreakCriteria(consider_end_as_break=True, m... 3.25 6 0.812500 87.109927 0.839166 0.640479
5 13118 13602 6 max_break MaxBreakCriteria(consider_end_as_break=True, m... 4.84 8 1.343333 92.247498 1.042166 0.833501
002 TimeMeasure1 Test5 Trial1 0 280 738 6 max_break MaxBreakCriteria(consider_end_as_break=True, m... 4.58 8 1.146667 92.522357 1.368916 1.114161
Trial2 0 220 592 5 max_break MaxBreakCriteria(consider_end_as_break=True, m... 3.72 7 1.230000 96.514193 1.562075 1.256416
Test11 Trial1 0 480 1138 7 max_break MaxBreakCriteria(consider_end_as_break=True, m... 6.58 9 1.501429 80.091127 0.877363 0.607347
1 2800 3275 6 max_break MaxBreakCriteria(consider_end_as_break=True, m... 4.75 8 1.408333 73.771578 0.836279 0.505248
2 5828 7892 22 max_break MaxBreakCriteria(consider_end_as_break=True, m... 20.64 27 1.163182 83.774692 0.853509 0.573635
3 15038 15520 5 max_break MaxBreakCriteria(consider_end_as_break=True, m... 4.82 7 1.424000 81.301579 0.588118 0.403409
MS 001 TimeMeasure1 Test5 Trial1 0 673 1185 8 max_break MaxBreakCriteria(consider_end_as_break=True, m... 5.12 10 1.127500 106.918436 1.125898 1.016039
Trial2 0 415 920 8 max_break MaxBreakCriteria(consider_end_as_break=True, m... 5.05 10 1.043750 107.443125 1.069114 0.995062
Test11 Trial1 0 979 1835 12 max_break MaxBreakCriteria(consider_end_as_break=True, m... 8.56 14 1.305000 92.900366 0.923630 0.746727
1 5230 5982 8 max_break MaxBreakCriteria(consider_end_as_break=True, m... 7.52 11 1.175000 87.808553 0.914782 0.650693
2 9715 10630 11 max_break MaxBreakCriteria(consider_end_as_break=True, m... 9.15 14 1.074545 100.575934 0.678129 0.571437
3 12994 14690 27 max_break MaxBreakCriteria(consider_end_as_break=True, m... 16.96 29 1.128148 100.810922 0.879267 0.741964
4 20287 22435 26 max_break MaxBreakCriteria(consider_end_as_break=True, m... 21.48 30 1.257692 84.225406 0.901833 0.638440


.. GENERATED FROM PYTHON SOURCE LINES 159-163 And the aggregated parameters. Note, that many values are NaN, because only a single WB was detected per trial. So we can not calculate the standard deviation or other statistics. To learn more about what the different aggregated values mean, check :class:`~mobgap.aggregation.MobilisedAggregator`. .. GENERATED FROM PYTHON SOURCE LINES 163-188 .. code-block:: Python aggregated_paras # Modifying Parameters # -------------------- # Both pipelines are basically the same, but the algorithms used for certain steps are different. # Both just reimplement :class:`~mobgap.pipeline.BaseMobilisedPipeline` with the respective algorithms as default # parameters. # So we can easily modify the parameters of the pipeline either using the ``set_params`` method or by passing different # parameters/algorithms to the constructor. # # .. warning:: As part of Mobilise-D we only validated the pipelines with their default values in exactly the cohorts we # recommend them for. # If you change the parameters, or use them in a different cohort, we ask you to not call this approach # "the Mobilised Pipeline" anymore, when communicating your results. # # Starting simple, let's say we simply don't want to filter and aggregate the final DMOs. # We just set the respective parameters to None. from mobgap.pipeline import MobilisedPipelineHealthy pipe_no_agg = MobilisedPipelineHealthy( dmo_thresholds=None, dmo_aggregation=None ) pipe_no_agg.safe_run(long_test_ha) .. rst-class:: sphx-glr-script-out .. code-block:: none MobilisedPipelineHealthy(cadence_calculation=CadFromIcDetector(ic_detector=IcdShinImproved(axis='norm'), max_interpolation_gap_s=3, silence_ic_warning=True, step_time_smoothing=HampelFilter(half_window_size=2, n_sigmas=3.0)), dmo_aggregation=None, dmo_thresholds=None, 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=IcdIonescu(cwt_width=9.0, pre_filter=EpflDedriftedGaitFilter(zero_phase=True)), 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=('HA', 'COPD', 'CHF'), 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 189-190 Now, the aggregated parameters are empty. .. GENERATED FROM PYTHON SOURCE LINES 190-192 .. code-block:: Python pipe_no_agg.aggregated_parameters_ .. GENERATED FROM PYTHON SOURCE LINES 193-194 And the per WB parameters are still there. .. GENERATED FROM PYTHON SOURCE LINES 194-196 .. code-block:: Python pipe_no_agg.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 630 1112 7 max_break MaxBreakCriteria(consider_end_as_break=True, m... 4.82 9 1.180000 102.691989 1.091216 0.937171
1 4488 5198 7 max_break MaxBreakCriteria(consider_end_as_break=True, m... 7.10 9 1.604286 91.361289 1.087672 0.826486
2 7848 8935 13 max_break MaxBreakCriteria(consider_end_as_break=True, m... 10.87 15 1.474615 78.868436 0.808942 0.559393
3 9390 10168 10 max_break MaxBreakCriteria(consider_end_as_break=True, m... 7.78 12 1.353000 92.854194 0.886643 0.672637
4 11140 11465 4 max_break MaxBreakCriteria(consider_end_as_break=True, m... 3.25 6 0.812500 87.109927 0.839166 0.640479
5 13118 13602 6 max_break MaxBreakCriteria(consider_end_as_break=True, m... 4.84 8 1.343333 92.247498 1.042166 0.833501


.. GENERATED FROM PYTHON SOURCE LINES 197-203 If you want to change the algorithm used for a certain step, you can simply pass a different algorithm to the constructor. For example, let's say you want to use the Adaptive Ionescu GSD algorithm instead of the GSDIluz (which is the default for the healthy pipeline). For the sake of this example, we will also modify the default parameters of the algorithm. .. GENERATED FROM PYTHON SOURCE LINES 203-209 .. code-block:: Python from mobgap.gait_sequences import GsdAdaptiveIonescu pipe_adaptive_gsd = MobilisedPipelineHealthy( gait_sequence_detection=GsdAdaptiveIonescu(min_n_steps=3) ) pipe_adaptive_gsd.safe_run(long_test_ha) .. rst-class:: sphx-glr-script-out .. code-block:: none MobilisedPipelineHealthy(cadence_calculation=CadFromIcDetector(ic_detector=IcdShinImproved(axis='norm'), max_interpolation_gap_s=3, silence_ic_warning=True, 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=GsdAdaptiveIonescu(active_signal_fallback_threshold=1.4709975, max_gap_s=3.5, min_n_steps=3, min_step_margin_s=1.5, padding=0.75), initial_contact_detection=IcdIonescu(cwt_width=9.0, pre_filter=EpflDedriftedGaitFilter(zero_phase=True)), 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=('HA', 'COPD', 'CHF'), 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 210-211 This works as before and all parameters of the pipeline are still available. .. GENERATED FROM PYTHON SOURCE LINES 211-213 .. code-block:: Python pipe_adaptive_gsd.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 6 0.885167 76 7.245 15.335 0.615597 91.194481 1.231413 0.054274 0.240333 2 0.773952 1.057163 2 0.790726 0 NaN NaN NaN NaN NaN NaN NaN NaN 0


.. GENERATED FROM PYTHON SOURCE LINES 214-216 .. code-block:: Python pipe_adaptive_gsd.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 533 1045 7 max_break MaxBreakCriteria(consider_end_as_break=True, m... 5.12 9 1.142857 99.102157 1.069263 0.910193
1 3853 5300 18 max_break MaxBreakCriteria(consider_end_as_break=True, m... 14.47 20 1.355000 86.077669 1.055774 0.752985
2 7740 8677 11 max_break MaxBreakCriteria(consider_end_as_break=True, m... 9.37 13 1.545455 90.565913 0.931816 0.695614
3 9532 10005 6 max_break MaxBreakCriteria(consider_end_as_break=True, m... 4.73 8 1.355000 88.367667 1.045279 0.771718
4 11142 11464 4 max_break MaxBreakCriteria(consider_end_as_break=True, m... 3.22 6 0.687500 95.074242 0.857767 0.662314
5 11982 13602 15 max_break MaxBreakCriteria(consider_end_as_break=True, m... 16.20 20 1.302667 87.979239 1.058551 0.794920


.. GENERATED FROM PYTHON SOURCE LINES 217-227 When you are planning to modify many algorithms, we would recommend to not use the specific pipeline classes anymore, to avoid the association (is it really still the Healthy pipeline if you change all algorithms?). In this case, we recommend the un-configured :class:`~mobgap.pipeline.GenericMobilisedPipeline`. This class is also used as the base class for the preconfigured pipelines. It has no algorithms set by default, so you have to set all algorithms yourself. See the end of the `step-by-step example `_ for a demonstration. If you want to reuse some of the defaults of the preconfigured pipelines, you can still use the ``PreconfiguredParameters``. For example, we could get the same pipeline as before like this: .. GENERATED FROM PYTHON SOURCE LINES 227-236 .. code-block:: Python from mobgap.pipeline import GenericMobilisedPipeline pipe_custom = GenericMobilisedPipeline( **dict( GenericMobilisedPipeline.PredefinedParameters.regular_walking, gait_sequence_detection=GsdAdaptiveIonescu(min_n_steps=3), ) ) pipe_adaptive_gsd.safe_run(long_test_ha) .. rst-class:: sphx-glr-script-out .. code-block:: none MobilisedPipelineHealthy(cadence_calculation=CadFromIcDetector(ic_detector=IcdShinImproved(axis='norm'), max_interpolation_gap_s=3, silence_ic_warning=True, 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=GsdAdaptiveIonescu(active_signal_fallback_threshold=1.4709975, max_gap_s=3.5, min_n_steps=3, min_step_margin_s=1.5, padding=0.75), initial_contact_detection=IcdIonescu(cwt_width=9.0, pre_filter=EpflDedriftedGaitFilter(zero_phase=True)), 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=('HA', 'COPD', 'CHF'), 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 237-239 .. code-block:: Python pipe_adaptive_gsd.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 6 0.885167 76 7.245 15.335 0.615597 91.194481 1.231413 0.054274 0.240333 2 0.773952 1.057163 2 0.790726 0 NaN NaN NaN NaN NaN NaN NaN NaN 0


.. GENERATED FROM PYTHON SOURCE LINES 240-242 .. code-block:: Python pipe_adaptive_gsd.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 533 1045 7 max_break MaxBreakCriteria(consider_end_as_break=True, m... 5.12 9 1.142857 99.102157 1.069263 0.910193
1 3853 5300 18 max_break MaxBreakCriteria(consider_end_as_break=True, m... 14.47 20 1.355000 86.077669 1.055774 0.752985
2 7740 8677 11 max_break MaxBreakCriteria(consider_end_as_break=True, m... 9.37 13 1.545455 90.565913 0.931816 0.695614
3 9532 10005 6 max_break MaxBreakCriteria(consider_end_as_break=True, m... 4.73 8 1.355000 88.367667 1.045279 0.771718
4 11142 11464 4 max_break MaxBreakCriteria(consider_end_as_break=True, m... 3.22 6 0.687500 95.074242 0.857767 0.662314
5 11982 13602 15 max_break MaxBreakCriteria(consider_end_as_break=True, m... 16.20 20 1.302667 87.979239 1.058551 0.794920


.. GENERATED FROM PYTHON SOURCE LINES 243-257 On the other end, if you are only planning to change a single sub-parameter of a pipeline, it might be easier to use the ``set_params`` method, instead of passing all parameters to the constructor. We show the extreme example of this here, by using the Universal-Pipeline as starting point and changing the filter order of the pre-processing filter of the GSD algorithm of the healthy pipeline used internally in the MetaPipeline. .. note:: The MobilisedPipelineUniversal is a special case, as it makes use of a tpcp feature called ``composite_params``. This allows us to target the ``pipelines__healthy`` parameters, even tough ``pipelines`` is not an object, but a list of tuples. Learn more about this feature in the `tpcp documentation `_. .. GENERATED FROM PYTHON SOURCE LINES 257-263 .. code-block:: Python from mobgap.pipeline import MobilisedPipelineUniversal meta_pipeline_modified = MobilisedPipelineUniversal().set_params( pipelines__healthy__gait_sequence_detection__pre_filter__order=50 ) .. GENERATED FROM PYTHON SOURCE LINES 264-268 This parameter name is a bit long, but it demonstrates that it is possible to change even deeply nested parameters. This might be in particular useful, when you want to run approaches like GridSearch. The algorithm works as before (note we don't expect any change in output for this parameter change). .. GENERATED FROM PYTHON SOURCE LINES 268-270 .. code-block:: Python meta_pipeline_modified.safe_run(long_test_ha) meta_pipeline_modified.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 6 0.644333 59 5.97 9.325 0.423421 90.855556 1.294622 0.085824 0.212845 1 0.559393 0.808942 1 0.559393 0 NaN NaN NaN NaN NaN NaN NaN NaN 0


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