2023-07-19 17:37:20 +08:00
#!/usr/bin/env python
# -*- coding: utf-8 -*-
'''
##################################################
## GAIT EVENTS DETECTION ##
##################################################
Determine gait events according to Zeni et al . ( 2008 ) .
Write them in gaitevents . txt ( append results if file already exists ) .
t_HeelStrike = max ( XHeel - Xsacrum )
t_ToeOff = min ( XToe - XSacrum )
Reference :
“ Two simple methods for determining gait events during treadmill and
overground walking using kinematic data . ”
Gait & posture vol . 27 , 4 ( 2008 ) : 710 - 4. doi : 10.1016 / j . gaitpost .2007 .07 .007
Usage :
Replace constants with the appropriate marker names .
If direction is negative , you need to include an equal sign in the argument ,
eg - d = - Z or - - gait_direction = - Z
from Pose2Sim . Utilities import trc_gaitevents ; trc_gaitevents . trc_gaitevents_func ( r ' <input_trc_file> ' , ' <gait_direction> ' )
2023-09-21 23:39:28 +08:00
OR python - m trc_gaitevents - i input_trc_file
OR python - m trc_gaitevents - i input_trc_file - - gait_direction = - Z
2023-07-19 17:37:20 +08:00
'''
## CONSTANTS
R_SACRUM_MARKER = ' RHip '
R_HEEL_MARKER = ' RHeel '
R_TOE_MARKER = ' RBigToe '
L_SACRUM_MARKER = ' LHip '
L_HEEL_MARKER = ' LHeel '
L_TOE_MARKER = ' LBigToe '
## INIT
import os
import argparse
import pandas as pd
import numpy as np
from scipy import signal
## AUTHORSHIP INFORMATION
__author__ = " David Pagnon "
__copyright__ = " Copyright 2021, Pose2Sim "
__credits__ = [ " David Pagnon " ]
__license__ = " BSD 3-Clause License "
2024-07-10 16:12:57 +08:00
__version__ = " 0.9.4 "
2023-07-19 17:37:20 +08:00
__maintainer__ = " David Pagnon "
__email__ = " contact@david-pagnon.com "
__status__ = " Development "
## FUNCTIONS
def df_from_trc ( trc_path ) :
'''
Retrieve header and data from trc path .
'''
# DataRate CameraRate NumFrames NumMarkers Units OrigDataRate OrigDataStartFrame OrigNumFrames
df_header = pd . read_csv ( trc_path , sep = " \t " , skiprows = 1 , header = None , nrows = 2 , encoding = " ISO-8859-1 " )
header = dict ( zip ( df_header . iloc [ 0 ] . tolist ( ) , df_header . iloc [ 1 ] . tolist ( ) ) )
# Label1_X Label1_Y Label1_Z Label2_X Label2_Y
df_lab = pd . read_csv ( trc_path , sep = " \t " , skiprows = 3 , nrows = 1 )
labels = df_lab . columns . tolist ( ) [ 2 : - 1 : 3 ]
labels_XYZ = np . array ( [ [ labels [ i ] + ' _X ' , labels [ i ] + ' _Y ' , labels [ i ] + ' _Z ' ] for i in range ( len ( labels ) ) ] , dtype = ' object ' ) . flatten ( )
labels_FTXYZ = np . concatenate ( ( [ ' Frame# ' , ' Time ' ] , labels_XYZ ) )
data = pd . read_csv ( trc_path , sep = " \t " , skiprows = 5 , index_col = False , header = None , names = labels_FTXYZ )
return header , data
def gait_events ( trc_path , gait_direction ) :
'''
Determine gait events according to Zeni et al . ( 2008 ) .
t_HellStrike = max ( XHeel - Xsacrum )
t_ToeOff = min ( XToe - XSacrum )
'''
# Read trc
header , data = df_from_trc ( trc_path )
# In case of a sign in direction (eg -Z)
sign = ' '
if any ( x in gait_direction for x in [ ' - ' , ' + ' ] ) :
sign = gait_direction [ 0 ]
gait_direction = gait_direction [ - 1 ]
# Retrieve data of interest
XRSacrum = data [ ' _ ' . join ( ( R_SACRUM_MARKER , gait_direction ) ) ]
XRHeel = data [ ' _ ' . join ( ( R_HEEL_MARKER , gait_direction ) ) ]
XRToe = data [ ' _ ' . join ( ( R_TOE_MARKER , gait_direction ) ) ]
XLSacrum = data [ ' _ ' . join ( ( L_SACRUM_MARKER , gait_direction ) ) ]
XLHeel = data [ ' _ ' . join ( ( L_HEEL_MARKER , gait_direction ) ) ]
XLToe = data [ ' _ ' . join ( ( L_TOE_MARKER , gait_direction ) ) ]
# Prominence of the peaks
unit = header [ ' Units ' ]
peak_prominence = .1 if unit == ' m ' else 1 if unit == ' dm ' else 10 if unit == ' cm ' else 100 if unit == ' mm ' else np . inf
# Right and left heel strikes
frame_RHS = signal . find_peaks ( eval ( sign + ' (XRHeel-XRSacrum) ' ) , prominence = peak_prominence ) [ 0 ]
t_RHS = data . loc [ frame_RHS , ' Time ' ] . tolist ( )
frame_LHS = signal . find_peaks ( eval ( sign + ' (XLHeel-XLSacrum) ' ) , prominence = peak_prominence ) [ 0 ]
t_LHS = data . loc [ frame_LHS , ' Time ' ] . tolist ( )
# Right and left toe offs
frame_RTO = signal . find_peaks ( eval ( sign + ' -(XRToe-XRSacrum) ' ) , prominence = peak_prominence ) [ 0 ]
t_RTO = data . loc [ frame_RTO , ' Time ' ] . tolist ( )
frame_LTO = signal . find_peaks ( eval ( sign + ' -(XLToe-XLSacrum) ' ) , prominence = peak_prominence ) [ 0 ]
t_LTO = data . loc [ frame_LTO , ' Time ' ] . tolist ( )
return t_RHS , t_LHS , t_RTO , t_LTO
def trc_gaitevents_func ( * args ) :
'''
Determine gait events according to Zeni et al . ( 2008 ) .
Write them in gaitevents . txt ( append results if file already exists ) .
t_HeelStrike = max ( XHeel - Xsacrum )
t_ToeOff = min ( XToe - XSacrum )
Reference :
“ Two simple methods for determining gait events during treadmill and
overground walking using kinematic data . ”
Gait & posture vol . 27 , 4 ( 2008 ) : 710 - 4. doi : 10.1016 / j . gaitpost .2007 .07 .007
Usage :
Replace constants with the appropriate marker names in trc_gaitevents . py .
If direction is negative , you need to include an equal sign in the argument ,
eg - d = - Z or - - gait_direction = - Z
import trc_gaitevents ; trc_gaitevents . trc_gaitevents_func ( r ' <input_trc_file> ' , ' <gait_direction> ' )
2023-09-21 23:39:28 +08:00
OR trc_gaitevents - i input_trc_file - - gait_direction Z
OR trc_gaitevents - i input_trc_file - - gait_direction = - Z
2023-07-19 17:37:20 +08:00
'''
try :
trc_path = args [ 0 ] . get ( ' input_file ' ) # invoked with argparse
gait_direction = args [ 0 ] [ ' gait_direction ' ]
except :
trc_path = args [ 0 ] # invoked as a function
try :
gait_direction = args [ 1 ]
except :
gait_direction = ' Z '
trc_dir = os . path . dirname ( trc_path )
trc_name = os . path . basename ( trc_path )
t_RHS , t_LHS , t_RTO , t_LTO = gait_events ( trc_path , gait_direction )
with open ( os . path . join ( trc_dir , ' gaitevents.txt ' ) , ' a ' ) as gaitevents :
L = trc_name + ' \n '
L + = ' Right Heel strikes: ' + str ( t_RHS ) + ' \n '
L + = ' Left Heel strikes: ' + str ( t_LHS ) + ' \n '
L + = ' Right Toe off: ' + str ( t_RTO ) + ' \n '
L + = ' Left Toe off: ' + str ( t_LTO ) + ' \n \n '
gaitevents . write ( L )
if __name__ == ' __main__ ' :
parser = argparse . ArgumentParser ( )
parser . add_argument ( ' -i ' , ' --input_file ' , required = True , help = ' trc input file ' )
parser . add_argument ( ' -d ' , ' --gait_direction ' , default = ' Z ' , required = False , help = ' direction of the gait. If negative, you need to include an equal sign in the argument, eg -d=-Z ' )
args = vars ( parser . parse_args ( ) )
trc_gaitevents_func ( args )