GsdIluz#

class mobgap.gait_sequences.GsdIluz(
*,
pre_filter: BaseFilter = cf(FirFilter(cutoff_freq_hz=(0.5, 3), filter_type='bandpass', order=200, window='hamming', zero_phase=True)),
window_length_s: float = 3,
window_overlap: float = 0.5,
std_activity_threshold: float = 0.0980665,
mean_activity_threshold: float = -0.980665,
acc_v_standing_threshold: float = 4.903325,
step_detection_thresholds: tuple[float, float] = (3.92266, 14.709975),
sin_template_freq_hz: float = 2,
allowed_steps_per_s: tuple[float, float] = (0.5, 3),
allowed_acc_v_change_per_window: float = 0.15,
min_gsd_duration_s: float = 5,
)[source]#

Implementation of the GSD algorithm by Iluz et al. (2014) [1].

The algorithm identifies steps in overlapping windows by convolving the data with a sin signal. Depending on the number of identified peaks, the window is classified as a gait sequence or not. Consecutive windows are then merged to form the final gait sequences.

This is based on the implementation published as part of the mobilised project [2]. However, this implementation deviates from the original implementation in some places. For details, see the notes section and the examples.

Parameters:
pre_filter

A pre-processing filter to apply to the data before the GSD algorithm is applied.

window_length_s

The length of the window in seconds that is used to detect gait sequences. Each window will be processed separately.

window_overlap

The overlap between two consecutive windows in percent. For example, a value of 0.5 means that the windows will overlap by 50%.

std_activity_threshold

The lower threshold for the standard deviation of the filtered acc_x data to be considered as activity.

mean_activity_threshold

A lower threshold applied to the mean of the mean-shifted raw gravity corrected acc_x data to be considered as activity.

acc_v_standing_threshold

A lower threshold applied to the mean of the acc_v data in each window to detect standing/upright positions. Only “standing” windows are considered for further processing.

step_detection_thresholds

The minimal peak height for the step detection. This expects a tuple with two values, one for each axis (acc_x and acc_z).

sin_template_freq_hz

The frequency of the sin template used for the convolution.

allowed_steps_per_s

A tuple with two values, specifying the lower and upper bound for the number of steps per second. This is converted in a minimum and maximum number of steps per window using the window_length_s parameter.

allowed_acc_v_change_per_window

The maximum change in the mean of the acc_v data between the first and the last second of the window in percent. I.e. 0.1 means a maximum change of 10%. If this change is exceeded, the window is discarded, as we assume that the person changed their posture (i.e from lying to standing).

min_gsd_duration_s

The minimum duration of a gait sequence in seconds. This is applied after the gait sequences are detected.

Other Parameters:
data

The raw IMU data in the body frame passed to the detect method.

sampling_rate_hz

The sampling rate of the IMU data in Hz passed to the detect method.

Attributes:
gs_list_

A dataframe specifying the detected gait sequences. The dataframe has a start and end column, specifying the start and end index of the gait sequence. The values are specified as samples after the start of the recording (i.e. the start of the data).

Notes

Points of deviation from the original implementation and their reasons:

  • The order of processing is changed. In the original implementation, steps are detected early on in the pipeline and later further thresholds on the raw signal are used to discard certain parts of the signal and non-gait. We flip the order to reduce the number of windows we need to apply step detection to. This is done, because the step detection process is the most expensive part of the algorithm.

  • Instead of a custom peak detection algorithm, we use the scipy implementation (find_peaks). This method produces similar but different results. Most notably, it does not have a maximal distance parameter. However, based on some testing, this parameter did not seem to have a big impact on the results, anyway. Overall, the scipy implementation seems to be more robust and detects less false positives (i.e. less peaks overall)

  • As the new find-peaks approach finds fewer peaks, we also change the threshold for the number of peaks per window. The original implementation expects 3 peaks per 3-second window. We use 0.5 steps per second as the lower bound, which means a minimum of 1.5/2 steps per 3-second window.

  • Similarly, the original implementation uses different thresholds for the two signal axis. I.e. different numbers of peaks are expected for the two axes. As this is not mentioned anywhere in the paper, and using the same threshold for both axis did not seem to have a negative impact on the results, we decided to use the same threshold for both axes to simplify the algorithm.

  • All parameters and thresholds are converted the units used in mobgap. Specifically, we use m/s^2 instead of g.

  • The original implementation used a check, that if the sum of the signal in the window is below the min-height threshold no peaks are detected. We assume that this is an error and use the max of the signal instead.

[1]

T. Iluz, E. Gazit, T. Herman, E. Sprecher, M. Brozgol, N. Giladi, A. Mirelman, and J. M. Hausdorff, “Automated detection of missteps during community ambulation in patients with parkinsons disease: a new approach for quantifying fall risk in the community setting,” J Neuroeng Rehabil, vol. 11, no. 1, p. 48, 2014.

Methods

clone()

Create a new instance of the class with all parameters copied over.

detect(data, *, sampling_rate_hz, **_)

Detect gait sequences in the passed data.

get_params([deep])

Get parameters for this algorithm.

self_optimize(data_sequences, ...)

Optimize the internal parameters of the algorithm.

set_params(**params)

Set the parameters of this Algorithm.

__init__(
*,
pre_filter: BaseFilter = cf(FirFilter(cutoff_freq_hz=(0.5, 3), filter_type='bandpass', order=200, window='hamming', zero_phase=True)),
window_length_s: float = 3,
window_overlap: float = 0.5,
std_activity_threshold: float = 0.0980665,
mean_activity_threshold: float = -0.980665,
acc_v_standing_threshold: float = 4.903325,
step_detection_thresholds: tuple[float, float] = (3.92266, 14.709975),
sin_template_freq_hz: float = 2,
allowed_steps_per_s: tuple[float, float] = (0.5, 3),
allowed_acc_v_change_per_window: float = 0.15,
min_gsd_duration_s: float = 5,
) None[source]#
clone() Self[source]#

Create a new instance of the class with all parameters copied over.

This will create a new instance of the class itself and all nested objects

detect(
data: DataFrame,
*,
sampling_rate_hz: float,
**_: Unpack[dict[str, Any]],
) Self[source]#

Detect gait sequences in the passed data.

Parameters:
data

The raw IMU data in the body frame.

sampling_rate_hz

The sampling rate of the IMU data in Hz.

Returns:
self

The instance of the class with the gs_list_ attribute set to the detected gait sequences.

get_params(deep: bool = True) dict[str, Any][source]#

Get parameters for this algorithm.

Parameters:
deep

Only relevant if object contains nested algorithm objects. If this is the case and deep is True, the params of these nested objects are included in the output using a prefix like nested_object_name__ (Note the two “_” at the end)

Returns:
params

Parameter names mapped to their values.

self_optimize(
data_sequences: Iterable[DataFrame],
ref_gsd_list_per_sequence: Iterable[DataFrame],
*,
sampling_rate_hz: float | Iterable[float],
**kwargs: Unpack[dict[str, Any]],
) Self[source]#

Optimize the internal parameters of the algorithm.

This is only relevant for algorithms that have a special internal optimization approach (like ML based algos).

Parameters:
data_sequences

A sequence/iterable/list of dataframes, each containing the raw IMU data of a single sensor. This could be individual trials or data from different participants. The optimization will be performed over all sequences combined.

ref_gsd_list_per_sequence

A sequence/iterable/list of gsd-list, each containing the reference gait sequences for the respective data sequence. They are used as ground-truth to validate the output of the algorithm during optimization.

sampling_rate_hz

The sampling rate of the IMU data in Hz. This can either be a single float, in case all sequences have the same sampling rate, or a sequence of floats, in case the sampling rate differs between the sequences.

Returns:
self

The instance of the class with the internal parameters optimized.

set_params(**params: Any) Self[source]#

Set the parameters of this Algorithm.

To set parameters of nested objects use nested_object_name__para_name=.

Examples using mobgap.gait_sequences.GsdIluz#

Custom Data and Datasets

Custom Data and Datasets

The Mobilise-D pipeline: Step-by-Step Breakdown

The Mobilise-D pipeline: Step-by-Step Breakdown

GSD Iluz

This example shows how to use the GSD Iluz algorithm and some examples on how the results compare to the original

GSD Evaluation

GSD Evaluation

GSD Evaluation Challenges

GSD Evaluation Challenges

GSD TVS Evaluation

GSD TVS Evaluation