Tutorial: Automatic EMG Events: Difference between revisions

From Software Product Documentation
Jump to navigation Jump to search
m (Text replacement - "www.c-motion.com/download" to "www.has-motion.com/download")
 
Line 22: Line 22:
== Preparing for the Tutorial ==
== Preparing for the Tutorial ==


'''Tutorial data download''': Files used in this tutorial can be found here: [[https://www.c-motion.com/download/examples/EMG_Tutorial.zip  EMG Tutorial]]  
'''Tutorial data download''': Files used in this tutorial can be found here: [[https://www.has-motion.com/download/examples/EMG_Tutorial.zip  EMG Tutorial]]  


The following pipeline has been provided as a '''meta_function''', and you may copy and paste it into your '''Visual3D x64 > Plugins > Meta-Commands''' folder. For more information on Meta-Commands and how they work, follow see [[Pipeline Commands:Meta Commands|here]].
The following pipeline has been provided as a '''meta_function''', and you may copy and paste it into your '''Visual3D x64 > Plugins > Meta-Commands''' folder. For more information on Meta-Commands and how they work, follow see [[Pipeline Commands:Meta Commands|here]].


'''Meta-Commands download''': Meta-Command file found here: [[https://www.c-motion.com/download/examples/EMG/Automatic_EMG_Events.v3m Automatic_EMG_Events]]
'''Meta-Commands download''': Meta-Command file found here: [[https://www.has-motion.com/download/examples/EMG/Automatic_EMG_Events.v3m Automatic_EMG_Events]]


== Loading Data and Calling the Meta-Function ==
== Loading Data and Calling the Meta-Function ==

Latest revision as of 11:20, 22 May 2024

Language:  English  • français • italiano • português • español 


Overview

Processing motion files with multiple EMG signals can become tedious when manually extracting events and identifying points of “rest”. We can manually detect sections of minimal activity within a motion trial to set as a reference threshold. Using the data download from Tutorial EMG, we can look at automatically detecting periods of low muscle activity to help us auto populate EMG onset/offset detection.

In this tutorial we will:

  1. Load EMG data into Visual 3D
  2. Perform a series of signal filtering commands including:
    1. Bandpass filter
    2. Full-wave rectify
    3. Moving Root Mean Squared (RMS)
    4. Teager-Kaiser Energy Operator (TKEO)
  3. Automatically detect low muscle activity
  4. Generate TKEO threshold to perform Onset Offset detection
  5. Visualize the event detection and demonstrate the effects of changing the meta parameters

Preparing for the Tutorial

Tutorial data download: Files used in this tutorial can be found here: [EMG Tutorial]

The following pipeline has been provided as a meta_function, and you may copy and paste it into your Visual3D x64 > Plugins > Meta-Commands folder. For more information on Meta-Commands and how they work, follow see here.

Meta-Commands download: Meta-Command file found here: [Automatic_EMG_Events]

Loading Data and Calling the Meta-Function

Open the trial_1.c3d file from the Tutorial download into Visual3D.

To begin the automatic detection, we first need to follow the typical processing procedure for EMG signals, going through all signals individually. We will work through the pipeline of Automatic_EMG_Events. You may look through the meta-command file along with this description, or use this pipeline to help build your own.

To call the meta-command in the pipeline, use the following:

Automatic_EMG_Events
/SIGNAL_NAMES=EMG_A+EMG_B+EMG_C
/ThresholdPercent=0.2
;

We can go through the meta-command pipeline itself to see what is being done. We begin by initializing the pipeline as a meta-command. This command will take two parameters, Signals_Names and ThresholdPercent. The signal names are associated with your EMGs and associated .c3d files. The threshold percent determines what percent of the maximum signal voltage you want to consider as noise or low muscle activity.

! BEGIN_META
! META_CMD_NAME=Automatic_EMG_Events
! META_PARAM= SIGNAL_NAMES:string::yes
! META_PARAM= ThresholdPercent:string::no
! META_HIGHPASS= 
! META_LOWPASS= 
! END_META

Processing and Filtering Raw EMG Signals

This meta command can be used to process EMG data in two ways; First, through the moving RMS filtering to remove noise from the analog signal while maintaining overall power, amplitude and energy, muscle activation patterns, and fatigue properties [1]. Second, TKEO will be used on the raw signals to perform a more rigorous filtration that will allow for onset/offset contraction detection. The TKEO will reduce power and amplitude but is more accurate when finding exact timing of events [2].

We initialize a for loop to go through all EMG signals in the open file.

For_Each
/Iteration_Parameter_Name= SIGNAL
/Items= ::SIGNAL_NAMES
;

Now we will look at filtering only at EMG data, if you wish to find GRFs or model_based_data, run a different pipeline before or after this one. First, a bandpass filter (high and lowpass) will be performed on raw analog signals. The highpass filter removes high frequency noise, the cutoff may need to be adjusted to suit your raw signals and how much noise there is. That is the ThresholdPercent parameter, and is expressed as a decimal.

In the ANALOG folder, several sub-folders will be generated in this section of the pipeline, as we go through the different filtering methods.

The PROCESSED data folder is going to contain the data that has gone through a highpass and lowpass filter.

The ENVELOPE data folder will contain filtered data in order of highpass, rectify, lowpass - this will be used later to help us find a resting period of the signal, with the ThresholdPercent parameter.

The PROCESSED_RMS data folder will take the PROCESSED data and perform moving RMS.

The PROCESSED_TKEO data folder will take the PROCESSED data and perform TKEO.

! Highpass filter removes large frquency noise from signal
Highpass_Filter
/SIGNAL_TYPES=ANALOG
/SIGNAL_FOLDER=ORIGINAL
/SIGNAL_NAMES=::SIGNAL
/RESULT_FOLDER=PROCESSED
! /RESULT_SUFFIX=
! /FILTER_CLASS=BUTTERWORTH
/FREQUENCY_CUTOFF=50
 /NUM_REFLECTED=0
! /NUM_EXTRAPOLATED=0
/TOTAL_BUFFER_SIZE=100
! /NUM_BIDIRECTIONAL_PASSES=1
;
! Rectify and Lowpass for envelop development (difference freq cutoff in lowpass filter)
Rectify
/SIGNAL_TYPES=ANALOG
/SIGNAL_NAMES=::SIGNAL
/SIGNAL_FOLDER=PROCESSED 
! /RESULT_NAMES=
! /RESULT_TYPES=
/RESULT_FOLDER=RECTIFY 
! /RESULT_SUFFIX=
;
Lowpass_Filter
 /SIGNAL_TYPES=ANALOG
/SIGNAL_FOLDER=RECTIFY
/SIGNAL_NAMES=::SIGNAL
/RESULT_FOLDER=ENVELOPE
! /RESULT_SUFFIX=
! /FILTER_CLASS=BUTTERWORTH
/FREQUENCY_CUTOFF=10
/NUM_REFLECTED=0
! /NUM_EXTRAPOLATED=0
 /TOTAL_BUFFER_SIZE=100
! /NUM_BIDIRECTIONAL_PASSES=1
;

Next, Lowpass filter will be applied to the original processed data for bandpass filtering. The lowpass filter removes any baseline drift, and again may need to be adjusted for your data. For more details on these filtering functions, see EMG Processing Tools.

Lowpass_Filter
 /SIGNAL_TYPES=ANALOG
/SIGNAL_FOLDER=PROCESSED
/SIGNAL_NAMES=::SIGNAL
/RESULT_FOLDER=PROCESSED
! /RESULT_SUFFIX=
! /FILTER_CLASS=BUTTERWORTH
/FREQUENCY_CUTOFF=80
/NUM_REFLECTED=0
! /NUM_EXTRAPOLATED=0
 /TOTAL_BUFFER_SIZE=100
! /NUM_BIDIRECTIONAL_PASSES=1
;
! RMS Filtering: Putting results in a new PROCESSED_RMS folder to identify which
! filtering process was used. Using the PROCESSED data from the bandpass filter
! to perform RMS on.
Moving_RMS
/SIGNAL_TYPES=ANALOG
/SIGNAL_FOLDER=PROCESSED
/SIGNAL_NAMES=::SIGNAL
! /RESULT_TYPES=
/RESULT_FOLDERS=PROCESSED_RMS
! /RESULT_NAME=
! /APPLY_AS_SUFFIX_TO_SIGNAL_NAME=
! /NUM_WINDOW_FRAMES=3
! /IF_EVEN_FRAMES_INCREMENT_1=FALSE
;
! TKEO Filtering: Putting results in a new PROCESSED_TKEO folder to identify which
! filtering process was used. Using the PROCESSED data from the bandpass filter
! to perform RMS on.
Teager_Kaiser_Energy
/SIGNAL_TYPES=ANALOG
/SIGNAL_FOLDER=PROCESSED
/SIGNAL_NAMES=::SIGNAL
!/SIGNAL_COMPONENTS=
 /RESULT_FOLDER=PROCESSED_TKEO
! /EVENT_SEQUENCE=
! /EXCLUDE_EVENTS=
;

Detecting Low Activity Signal Regions

This section will essentially perform on/off detection of the ENVELOPE signal with an arbitrary baseline that we define with a user-given parameter.

Event detection using Analog signal envelop method: Creates events that define the resting baseline of the muscle. We will find the resting period based on an arbitrary value that the user can change. For this example, we use 20% of the maximum signal of the ENVELOPE (which is a highly smoothed signal). After we find the rest period, we compute the median and standard deviation to find an appropriate baseline for ON/OFF detection of muscle activation that can be used on TKEO signals.

When we run this pipeline section, you can open your ENVELOPE analog signals and highlight the ASCENT and DESCENT events that are associated with each signal. Here, you can determine if the ThresholdPercent parameter is at an appropriate level for your signals. Increasing the ThresholdPercent will consider more of the signal to be “rest”, or noise, and lowering the ThresholdPercent will decrease the noise that you include in your “resting” data.

Find Maximum for each signal

Metric_Maximum
/RESULT_METRIC_FOLDER=PROCESSED
/RESULT_METRIC_NAME=::SIGNAL&MAX
/APPLY_AS_SUFFIX_TO_SIGNAL_NAME=FALSE
/SIGNAL_TYPES= ANALOG
/SIGNAL_FOLDER=ENVELOPE
/SIGNAL_NAMES=::SIGNAL
! /COMPONENT_SEQUENCE=
!/EVENT_SEQUENCE=
!/EXCLUDE_EVENTS=
! /GENERATE_MEAN_AND_STDDEV=TRUE
! /APPEND_TO_EXISTING_VALUES=FALSE
! /CREATE_GLOBAL_MAXIMUM=FALSE
! /CREATE_TRIAL_MAXIMUM=FALSE
;

Find Events when signal crosses threshold that is some specified % of metric max, to find "activation" and "rest"

! Set threshold
Set_Pipeline_Parameter_From_Expression
/PARAMETER_NAME= THRESH
/EXPRESSION=(METRIC::PROCESSED::&::SIGNAL&MAX)*&::ThresholdPercent
/AS_INTEGER=FALSE
;
! Find when signal "ascents" above threshold
Metric_Time_Of_Threshold_From_Event
/RESULT_EVENT_NAME=::SIGNAL&ASCENT
/SIGNAL_TYPES=ANALOG
/SIGNAL_NAMES=::SIGNAL
/SIGNAL_FOLDER=ENVELOPE
/SIGNAL_COMPONENTS=X
! /FRAME_OFFSET=0
! /TIME_OFFSET=
! /EVENT_SEQUENCE=
! /EXCLUDE_EVENTS=
!/EVENT_SEQUENCE_INSTANCE=0
! /EVENT_SUBSEQUENCE=
! /SUBSEQUENCE_EXCLUDE_EVENTS=
! /EVENT_SUBSEQUENCE_INSTANCE=0
/EVENT_INSTANCE=0
/SELECT_X=TRUE
! /SELECT_Y=
! /SELECT_Z=
! /SELECT_RESIDUAL=
! /START_AT_EVENT=
! /END_AT_EVENT=
/THRESHOLD=::THRESH
/ON_ASCENT=TRUE
!/ON_DESCENT=
! /FRAME_WINDOW=8
! /ENSURE_FRAMES_BEFORE=
! /ENSURE_FRAMES_AFTER=
;
! Find when signal "descents" below threshold
Metric_Time_Of_Threshold_From_Event
/RESULT_EVENT_NAME=::SIGNAL&DESCENT
/SIGNAL_TYPES=ANALOG
/SIGNAL_NAMES=::SIGNAL
/SIGNAL_FOLDER=ENVELOPE
/SIGNAL_COMPONENTS=X
! /FRAME_OFFSET=0
! /TIME_OFFSET=
! /EVENT_SEQUENCE=
! /EXCLUDE_EVENTS=
!/EVENT_SEQUENCE_INSTANCE=0
! /EVENT_SUBSEQUENCE=
! /SUBSEQUENCE_EXCLUDE_EVENTS=
! /EVENT_SUBSEQUENCE_INSTANCE=0
/EVENT_INSTANCE=0
/SELECT_X=TRUE
! /SELECT_Y=
! /SELECT_Z=
! /SELECT_RESIDUAL=
! /START_AT_EVENT=
! /END_AT_EVENT=
/THRESHOLD=::THRESH
/ON_ASCENT=FALSE
/ON_DESCENT=TRUE
! /FRAME_WINDOW=8
! /ENSURE_FRAMES_BEFORE=
! /ENSURE_FRAMES_AFTER=
;

Now define events at the times of "ascent" and "descent". A period of time between descent to ascent should be an area of low activity and just noise.

Event_Explicit
/EVENT_NAME=::SIGNAL&ASCENT
!/FRAME=1
/TIME=METRIC::PROCESSED::&::SIGNAL&ASCENT
;
Event_Explicit
/EVENT_NAME=::SIGNAL&DESCENT
!/FRAME=150
/TIME=METRIC::PROCESSED::&::SIGNAL&DESCENT
;

Onset/Offset Detection

Now that we have ASCENT and DESCENT events of our EMG envelopes, we can consider low activity or “rest” periods to be between descent - ascent events. The reason we cannot officially define these events as onset or offset of the muscle, is because it is more correct to use the TKEO signal with a threshold of median + 3*stdv of the “resting” signal. So now we have identified the resting periods of each signal and can find our official onset and offset thresholds.

Here we compute the median and standard deviation of the TKEO envelope during defined "rest". We have the events to define a period of rest, and we can define these times for the TKEO signal. TKEO is used to define ON/OFF for muscle activity by identify that the signal is on based on a threshold crossing of the median + 3 * standard deviation (from TKEO filtered data specifically. For more detail, EMG Onset Based on TKO or reference [3]).

Metric_Median
/RESULT_METRIC_NAME=_MED
/APPLY_AS_SUFFIX_TO_SIGNAL_NAME=TRUE
/RESULT_METRIC_FOLDER=EMG_TKEO
/SIGNAL_TYPES=ANALOG
/SIGNAL_NAMES=::SIGNAL
/SIGNAL_FOLDER=PROCESSED_TKEO
! /SIGNAL_COMPONENTS=ALL_COMPONENTS
/EVENT_SEQUENCE=::SIGNAL&DESCENT+::SIGNAL&ASCENT
/EXCLUDE_EVENTS=
/GENERATE_MEAN_AND_STDDEV=TRUE
! /APPEND_TO_EXISTING_VALUES=FALSE
;
Metric_StdDev
/RESULT_METRIC_NAME=_SD
/APPLY_AS_SUFFIX_TO_SIGNAL_NAME=TRUE
/RESULT_METRIC_FOLDER=EMG_TKEO
/SIGNAL_TYPES=ANALOG
/SIGNAL_NAMES=::SIGNAL
/SIGNAL_FOLDER=PROCESSED_TKEO
! /SIGNAL_COMPONENTS=ALL_COMPONENTS
/EVENT_SEQUENCE=::SIGNAL&DESCENT+::SIGNAL&ASCENT
/EXCLUDE_EVENTS=
/GENERATE_MEAN_AND_STDDEV=TRUE
! /APPEND_TO_EXISTING_VALUES=FALSE
;

Identify the event EMG_C_ON based on a threshold crossing

!of the median + 3 * standard deviation
Set_Pipeline_Parameter_From_Expression
/PARAMETER_NAME= THRESH2
/EXPRESSION=(METRIC::EMG_TKEO::&::SIGNAL&_MED_MEAN)+3*(METRIC::EMG_TKEO::&::SIGNAL&_SD_MEAN)
/AS_INTEGER=FALSE
;
! Create threshold line vector for plotting purposes
Create_Target
/SIGNAL_NAMES=::SIGNAL&_Threshold
! /SIGNAL_DESCRIPTION=
/EXPRESSION=VECTOR(&::THRESH2&,0,0)
! /INCLUDE_MOTIONFILE=TRUE
! /INCLUDE_CALFILE=FALSE
;

Defining signal OFF based on descending through the new threshold

Metric_Time_Of_Threshold_From_Event
/RESULT_EVENT_NAME=::SIGNAL&OFF
/SIGNAL_TYPES=ANALOG
/SIGNAL_NAMES=::SIGNAL
/SIGNAL_FOLDER=PROCESSED_TKEO
/SIGNAL_COMPONENTS=X
! /FRAME_OFFSET=0
! /TIME_OFFSET=
! /EVENT_SEQUENCE=
! /EXCLUDE_EVENTS=
!/EVENT_SEQUENCE_INSTANCE=0
! /EVENT_SUBSEQUENCE=
! /SUBSEQUENCE_EXCLUDE_EVENTS=
! /EVENT_SUBSEQUENCE_INSTANCE=0
/EVENT_INSTANCE=0
/SELECT_X=TRUE
! /SELECT_Y=
! /SELECT_Z=
! /SELECT_RESIDUAL=
! /START_AT_EVENT=
! /END_AT_EVENT=
/THRESHOLD=::THRESH2
/ON_ASCENT=FALSE
/ON_DESCENT=TRUE
! /FRAME_WINDOW=8
! /ENSURE_FRAMES_BEFORE=
! /ENSURE_FRAMES_AFTER=
;

Creating an event for the OFF detection

Event_Explicit
/EVENT_NAME=::SIGNAL&OFF
!/FRAME=1
/TIME=METRIC::PROCESSED::&::SIGNAL&OFF
;

Defining signal ON based on ascending through the new threshold

Metric_Time_Of_Threshold_From_Event
/RESULT_EVENT_NAME=::SIGNAL&ON
/SIGNAL_TYPES=ANALOG
/SIGNAL_NAMES=::SIGNAL
/SIGNAL_FOLDER=PROCESSED_TKEO
/SIGNAL_COMPONENTS=X
! /FRAME_OFFSET=0
! /TIME_OFFSET=
! /EVENT_SEQUENCE=
! /EXCLUDE_EVENTS=
!/EVENT_SEQUENCE_INSTANCE=0
! /EVENT_SUBSEQUENCE=
! /SUBSEQUENCE_EXCLUDE_EVENTS=
! /EVENT_SUBSEQUENCE_INSTANCE=0
/EVENT_INSTANCE=0
/SELECT_X=TRUE
! /SELECT_Y=
! /SELECT_Z=
! /SELECT_RESIDUAL=
! /START_AT_EVENT=
! /END_AT_EVENT=
/THRESHOLD=::THRESH2
/ON_ASCENT=TRUE
/ON_DESCENT=FALSE
! /FRAME_WINDOW=8
! /ENSURE_FRAMES_BEFORE=
! /ENSURE_FRAMES_AFTER=
;

Creating an event for the ON detection

Event_Explicit
/EVENT_NAME=::SIGNAL&ON
!/FRAME=1
/TIME=METRIC::PROCESSED::&::SIGNAL&ON
;

Visualizing Event Detection

There we go! We have automatically found onset and offset for all signals, and can look at these events in our data. Before this, we end the for loop for the meta-function.

End_For_Each
/Iteration_Parameter_Name=SIGNAL
;

We can now take a look at our onset and offset detection.

Select a TKEO processed signal from the ANALOG > PROCESSED_TKEO folder and plot a new graph.

Under EVENT_LABEL > ORIGINAL, select the 'signalName'ON and 'signalName'OFF events for the signal plotted.

You can see on the signal there are faint pink lines all across the signal, that do not all get highlighted when the events are selected. This is because event assignment happens at then file level, not at the signal level. So these events are being assigned to the entire motion file each time we define an event for one of the signals. This is why it is important that you highlight only the events associated with the signal you are looking at.

We can see from these figures that there are a lot of ON and OFF detections for the TKEO signal. This is due to a lot of fluctuation and noise in the signal, and the threshold is passed through many times where there is large muscle activity.

If you find the automatic detection is identify data fluctuation that is too low in amplitude for your liking, we can adjust the ThresholdPercent parameter to change this. For example, this meta-command was re-run on this data using ThresholdPercent = 0.6, and the following results were found. We can see that only muscle activity of high magnitude were noted as ON/OFF events.

References

1. Amedeo Troiano, Francesco Naddeo, Erik Sosso, Gianfranco Camarota, Roberto Merletti, Luca Mesin, Assessment of force and fatigue in isometric contractions of the upper trapezius muscle by surface EMG signal and perceived exertion scale, Gait & Posture 2018

2. José A. Biurrun Manresa, Carsten D. Mørch, and Ole K. Andersen, Teager-Kaiser Energy Operator Improves the Detection and Quantification of Nociceptive Withdrawal Reflexes From Surface Electromyography, IEEE

3. [Solnik S, DeVita P, Rider P, Long B, and Hortobágyi T (2008) Teager–Kaiser Operator improves the accuracy of EMG onset detection independent of signal-to-noise ratio, Acta Bioeng Biomech. 2008 ; 10(2): 65–68]

Retrieved from ""