Tutorial: Automatic EMG Events: Difference between revisions

From Software Product Documentation
Jump to navigation Jump to search
Line 151: Line 151:


== Detecting Low Activity Signal Regions ==
== Detecting Low Activity Signal Regions ==
[[File:ENVELOPE.png|right|1000px]]
This section will essentially perform on/off detection of the '''ENVELOPE''' signal with an arbitrary baseline that we define with a user-given parameter.
This section will essentially perform on/off detection of the '''ENVELOPE''' signal with an arbitrary baseline that we define with a user-given parameter.


Line 157: Line 158:


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.  
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.  
[[File:ENVELOPE.png|right|600px]]
 
  ! Step 1
  ! Step 1
  ! Find Maximum for each signal
  ! Find Maximum for each signal

Revision as of 15:18, 15 May 2023

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:

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 tutorial_.

meta-commands download:

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.

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 [cite]. 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 [cite].

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. See TUTORIAL for an example of how the filtered data should look. For more details on these filtering functions, see cite.

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.

! Step 1
! 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
;
! Step 2
! 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
;
Retrieved from ""