====== Linear Envelope ======
Computing the onset of an EMG signal can be quite tricky. In this example, we describe a pipeline for a straightforward estimation of EMG onset based on the EMG envelope and [[Visual3D:Documentation:Pipeline:Event_Commands:Event_Threshold|Event_Threshold]]. This is not a definitive definition, but simply a starting point for the user.
{{:Emg2.jpg}}
Three event labels are identified on this figure. The yellow and red events specify the "rest period". This is arbitrary and is specified by the user explicitly. The blue event label is the first threshold crossing above the "median + 3*standard deviation".
!Apply a high pass and low pass filter assuming that the surface emg signal contains information
!from 20 to 500 Hz
Highpass_Filter
/SIGNAL_TYPES=ANALOG
/SIGNAL_NAMES=EMG2
! /SIGNAL_FOLDER=ORIGINAL
! /RESULT_SUFFIX=
/RESULT_FOLDER=RMS
! /FILTER_CLASS=BUTTERWORTH
/FREQUENCY_CUTOFF=20
/NUM_REFLECTED=0
/TOTAL_BUFFER_SIZE=100
! /NUM_BIDIRECTIONAL_PASSES=1
;
Lowpass_Filter
/SIGNAL_TYPES=ANALOG
! /SIGNAL_NAMES=
/SIGNAL_FOLDER=RMS
! /RESULT_SUFFIX=
/RESULT_FOLDER=RMS
! /FILTER_CLASS=BUTTERWORTH
/FREQUENCY_CUTOFF=500
/NUM_REFLECTED=0
/TOTAL_BUFFER_SIZE=100
! /NUM_BIDIRECTIONAL_PASSES=1
;
!Compute the RMS of the emg signal based on a 100 ms window
Moving_RMS
/SIGNAL_TYPES=ANALOG
/SIGNAL_NAMES=EMG2
/SIGNAL_FOLDER=RMS
! /RESULT_SUFFIX=
/RESULT_FOLDER=RMS
/NUM_WINDOW_FRAMES=1+0.1*PARAMETER::ANALOG::RATE
;
!Create events that define the resting baseline of the muscle
Event_Explicit
/EVENT_NAME=REST1
/FRAME=1
! /TIME=
;
Event_Explicit
/EVENT_NAME=REST2
/FRAME=150
! /TIME=
;
!Compute the median and standard deviation of the EMG envelope during rest
Metric_Median
/RESULT_METRIC_NAME=_MED
/APPLY_AS_SUFFIX_TO_SIGNAL_NAME=TRUE
/RESULT_METRIC_FOLDER=EMG
/SIGNAL_TYPES=ANALOG
/SIGNAL_NAMES=EMG2
/SIGNAL_FOLDER=RMS
! /SIGNAL_COMPONENTS=ALL_COMPONENTS
/EVENT_SEQUENCE=REST1+REST2
/EXCLUDE_EVENTS=
/GENERATE_MEAN_AND_STDDEV=FALSE
! /APPEND_TO_EXISTING_VALUES=FALSE
;
Metric_StdDev
/RESULT_METRIC_NAME=_SD
/APPLY_AS_SUFFIX_TO_SIGNAL_NAME=TRUE
/RESULT_METRIC_FOLDER=EMG
/SIGNAL_TYPES=ANALOG
/SIGNAL_NAMES=EMG2
/SIGNAL_FOLDER=RMS
! /SIGNAL_COMPONENTS=ALL_COMPONENTS
/EVENT_SEQUENCE=REST1+REST2
/EXCLUDE_EVENTS=
/GENERATE_MEAN_AND_STDDEV=FALSE
! /APPEND_TO_EXISTING_VALUES=FALSE
;
!Identify the event EMG2_ON based on a threshold crossing
!of the median + 3 * standard deviation
Event_Threshold
/SIGNAL_TYPES=ANALOG
/SIGNAL_NAMES=EMG2
/SIGNAL_FOLDER=RMS
/EVENT_NAME=EMG2_ON
/SELECT_X=TRUE
! /SELECT_Y=FALSE
! /SELECT_Z=FALSE
! /SELECT_RESIDUAL=FALSE
/THRESHOLD=METRIC::EMG::EMG2_MED+3*METRIC::EMG::EMG2_SD
! /FRAME_WINDOW=8
! /FRAME_OFFSET=0
/ASCENDING=TRUE
! /DESCENDING=FALSE
! /ENSURE_RANGE_FRAMES_BEFORE_THRESHOLD_CROSSING=FALSE
/ENSURE_RANGE_FRAMES_AFTER_THRESHOLD_CROSSING=TRUE
! /START_AT_EVENT=
! /END_AT_EVENT=
/EVENT_INSTANCE=1
;
\\
==== Count the Number of Frames the signals is ON ====
! Create a signal that is zero when the EMG is off, and one when it is ON
! Start with creating a signal that is zero at all frames
Evaluate_Expression
/EXPRESSION=FRAME_NUMBERS::ORIGINAL::FRAMES * 0
! /SIGNAL_TYPES=
! /SIGNAL_FOLDER=ORIGINAL
! /SIGNAL_NAMES=
/RESULT_TYPES=DERIVED
/RESULT_FOLDERS=EMG_COUNT
/RESULT_NAME=EMG2
! /APPLY_AS_SUFFIX_TO_SIGNAL_NAME=FALSE
;
! Set all frames between the ON/OFF events to one
Set_Data_To_New_Values
/SIGNAL_TYPES=DERIVED
/SIGNAL_FOLDER=EMG_COUNT
/SIGNAL_NAMES=EMG2
! /SIGNAL_COMPONENTS=ALL_COMPONENTS
/RESULT_TYPES=DERIVED
/RESULT_FOLDERS=EMG_COUNT
/RESULT_SUFFIX=
/EVENT_SEQUENCE=EMG2_ON+EMG2_OFF
! /EXCLUDE_EVENTS=
! /EVENT_INSTANCE=0
! /START_FRAME=
! /END_FRAME=
! /USE_POINT_RATE=TRUE
/REPLACEMENT_VALUES=1
! /THRESHOLD_HIGH=NO_DATA
! /THRESHOLD_LOW=NO_DATA
! /SET_DATA_AT_SINGLE_EVENT=FALSE
;
! Add the signal during the gait cycle
! The result will be the number of frames the signal is ON during the gait cycle
Metric_Sum
/RESULT_METRIC_FOLDER=EMG_COUNT
/RESULT_METRIC_NAME=
/APPLY_AS_SUFFIX_TO_SIGNAL_NAME=TRUE
/SIGNAL_TYPES=DERIVED
/SIGNAL_FOLDER=EMG_COUNT
/SIGNAL_NAMES=EMG2
/COMPONENT_SEQUENCE=ALL
/EVENT_SEQUENCE=RHS+RHS
/EXCLUDE_EVENTS=
/SEQUENCE_PERCENT_START=
/SEQUENCE_PERCENT_END=
! /GENERATE_MEAN_AND_STDDEV=TRUE
! /APPEND_TO_EXISTING_VALUES=FALSE
;