GsdIluz#
- class mobgap.gait_sequences.GsdIluz(
- *,
- pre_filter: BaseFilter = cf(FirFilter(cutoff_freq_hz=(0.5, 3), filter_type='bandpass', order=100, window='hamming', zero_phase=True)),
- window_length_s: float = cf(3),
- window_overlap: float = cf(0.5),
- std_activity_threshold: float = cf(0.0980665),
- mean_activity_threshold: float = cf(-0.980665),
- acc_v_standing_threshold: float = cf(4.903325),
- step_detection_thresholds: tuple[float, float] = cf((0.0392266, 0.04903325)),
- sin_template_freq_hz: float = cf(2),
- allowed_steps_per_s: tuple[float, float] = cf((0.6666666666666666, 3)),
- allowed_acc_v_change_per_window: float = cf(0.15),
- min_gsd_duration_s: float = cf(5),
- use_original_peak_detection: bool = cf(False),
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_sparameter.- 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.
- use_original_peak_detection
If True, the original peak detection algorithm is used. It uses zero crossings to identify peaks and further interpolate the existence of peaks, when none are found for a certain period of time. We default to the new peak detection algorithm, as it is simpler and less magic. The performance of the two algorithms is similar, but not identical. For the best possible performance with the original algorithm, some of the other parameters might need to be adjusted.
- Other Parameters:
- data
The raw IMU data in the body frame passed to the
detectmethod.- sampling_rate_hz
The sampling rate of the IMU data in Hz passed to the
detectmethod.
- Attributes:
- gs_list_
A dataframe specifying the detected gait sequences. The dataframe has a
startandendcolumn, 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 thedata).- perf_
A dictionary with the performance results of the action method. This includes:
start_datetime_utc_timestamp: The start time of the action in UTC as a timestamp.
start_datetime: The start time of the action as a string.
end_datetime_utc_timestamp: The end time of the action in UTC as a timestamp.
end_datetime: The end time of the action as a string.
runtime_s: The runtime of the action in seconds.
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 a simple peak detection algorithm based on the version implemented in scipy, by default. We reimplemented in
numbafor significant speedup. This method produces similar but different results. Most notably, it does not have a maximal distance parameter and does not “interpolate” peaks, if large gaps between peaks are detected. This means, that the new method often reduces the number of detected peaks. To counter act this, we use a significantly lower signal threshold for the pa-axis. The orignal value was 1.2 g, we use 0.5 g.A reimplementation of the original implementation can be used by setting
use_original_peak_detection=True. However, we default to the new one, as it is “less” magic.The original implementation uses different lower threshold for the allowed numbers per step. 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.
The filter order of the pre-filter is reduced to 100 from 200, as we use a filtfilt implementation, instead of just forward filtering.
We normalize the convolution by the sampling rate. Otherwise, the amplitude of the convolution would scale with the sampling rate and the thresholds would need to be adjusted accordingly. This was already a problem in the original version, as the same code was used with 128 Hz and published for the use with 100 Hz.
[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.
PredefinedParameters
- __init__(
- *,
- pre_filter: BaseFilter = cf(FirFilter(cutoff_freq_hz=(0.5, 3), filter_type='bandpass', order=100, window='hamming', zero_phase=True)),
- window_length_s: float = cf(3),
- window_overlap: float = cf(0.5),
- std_activity_threshold: float = cf(0.0980665),
- mean_activity_threshold: float = cf(-0.980665),
- acc_v_standing_threshold: float = cf(4.903325),
- step_detection_thresholds: tuple[float, float] = cf((0.0392266, 0.04903325)),
- sin_template_freq_hz: float = cf(2),
- allowed_steps_per_s: tuple[float, float] = cf((0.6666666666666666, 3)),
- allowed_acc_v_change_per_window: float = cf(0.15),
- min_gsd_duration_s: float = cf(5),
- use_original_peak_detection: bool = cf(False),
- 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( ) 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]],
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.
Examples using mobgap.gait_sequences.GsdIluz#
Revalidation of the gait sequence detection algorithms