visual3d:documentation:emg:processing:normalize_emg_to_mvc
Table of Contents
Normalize EMG to MVC
Normalize EMG Signal to Maximum Within Gait Cycle
For this example, the goal is as follows:
- Process the raw EMG signal
- In this example, a simple linear envelope was done and saved in ANALOG::ENVELOPE
- Compute the maximum of the EMG signal during each gait cycle
- Normalize the EMG signal to the maximum during each gait cycle
Sample Files
You can download the sample files here.
The download contains:
- Sample_Workspace.cmz with -
- 2 Dynamic Trials
- Processed EMG signals (ANALOG::ENVELOPE), you should use your own processing, not the example processing used to create this envelope signal
- EMG_Norm_Gait_Cycle.v3s (Example Pipeline Script)
- EMG_Norm_Gait_Cycle.v3m (Example Meta-Command)
- Call_EMG_Norm_Gait_Cycle_Meta.v3s (Example Pipeline Script calling Meta-Command)
Script Explanation
Example Pipeline Script
Set_Pipeline_Parameter /PARAMETER_NAME=R_EMG_SIGNAL_LIST /PARAMETER_VALUE=EMG_A+EMG_B+EMG_C ! /PARAMETER_VALUE_SEARCH_FOR= ! /PARAMETER_VALUE_REPLACE_WITH= ! /PARAMETER_VALUE_PREFIX= ! /PARAMETER_VALUE_APPEND= ! /MULTI_PASS=FALSE ; Set_Pipeline_Parameter /PARAMETER_NAME=L_EMG_SIGNAL_LIST /PARAMETER_VALUE=EMG_A+EMG_B+EMG_C ! /PARAMETER_VALUE_SEARCH_FOR= ! /PARAMETER_VALUE_REPLACE_WITH= ! /PARAMETER_VALUE_PREFIX= ! /PARAMETER_VALUE_APPEND= ! /MULTI_PASS=FALSE ; Select_Active_File /FILE_NAME=ALL_FILES ! /QUERY= ; Event_Define_Event_Sequence /EVENT_SEQUENCE_NAME=RCYCLE_SEQUENCE /EVENT_SEQUENCE=RHS+RTO ! /EXCLUDE_EVENTS= ! /INSIDE_OF_SEQUENCE= ! /OFFSET_FROM_START= ! /OFFSET_FROM_END= ! /OFFSET_BY=PERCENT /EVENT_SEQUENCE_INSTANCE=0 ; Event_Define_Event_Sequence /EVENT_SEQUENCE_NAME=LCYCLE_SEQUENCE /EVENT_SEQUENCE=LHS+LTO ! /EXCLUDE_EVENTS= ! /INSIDE_OF_SEQUENCE= ! /OFFSET_FROM_START= ! /OFFSET_FROM_END= ! /OFFSET_BY=PERCENT /EVENT_SEQUENCE_INSTANCE=0 ; For_Each /ITERATION_PARAMETER_NAME=SIDE ! /ITERATION_PARAMETER_COUNT_NAME= /ITEMS=R+L ; Set_Pipeline_Parameter /PARAMETER_NAME=EMG_SIGNAL_LIST /PARAMETER_VALUE=:&:&::SIDE&_EMG_SIGNAL_LIST ! /PARAMETER_VALUE_SEARCH_FOR= ! /PARAMETER_VALUE_REPLACE_WITH= ! /PARAMETER_VALUE_PREFIX= ! /PARAMETER_VALUE_APPEND= /MULTI_PASS=TRUE ; ! --------------------------------------------------------------------- ! Get the maximum number of cycles in a trial the entire CMZ file ! --------------------------------------------------------------------- ! We're going to loop over every sequence in the trial, ! so first calculate the maximum number of sequences in the longest trial ! Count the number of cycles in each trial Metric_Event_Sequence_Count /RESULT_METRIC_FOLDER=EMG_NORM /RESULT_METRIC_NAME=&::SIDE&Cycle_Count ! /TIME_INTERVAL= /EVENT_SEQUENCE=&::SIDE&CYCLE_SEQUENCE /EXCLUDE_EVENTS= /GENERATE_COUNT_TOTAL_IN_GLOBAL=FALSE ; ! Calculate the maximum number of cycles across all trials Metric_Maximum /RESULT_METRIC_FOLDER=EMG_NORM /RESULT_METRIC_NAME=&::SIDE&Cycle_Count_Global ! /APPLY_AS_SUFFIX_TO_SIGNAL_NAME=FALSE /SIGNAL_TYPES=METRIC /SIGNAL_FOLDER=EMG_NORM /SIGNAL_NAMES=&::SIDE&Cycle_Count /COMPONENT_SEQUENCE=ALL /EVENT_SEQUENCE= /EXCLUDE_EVENTS= /SEQUENCE_PERCENT_START= /SEQUENCE_PERCENT_END= /GENERATE_MEAN_AND_STDDEV=FALSE ! /APPEND_TO_EXISTING_VALUES=FALSE /CREATE_GLOBAL_MAXIMUM=TRUE ; ! Create a list from 1 to the maximum event sequence in steps of 1 Set_Pipeline_Parameter_From_For_Loop /PARAMETER_NAME=SEQUENCE_COUNT /PARAMETER_INDEX_START=1 /PARAMETER_INDEX_END=GLOBAL::METRIC::EMG_NORM::&::SIDE&Cycle_Count_Global_Max /PARAMETER_INDEX_STEP=1 /PARAMETER_INDEX_TYPE=INTEGER ; ! --------------------------------------------------------------------- ! Create Normalize Signal ! --------------------------------------------------------------------- ! Create a temporary signal which contains zeros at all frames Evaluate_Expression /EXPRESSION=CURRENT_SIGNAL * 0 /SIGNAL_TYPES=ANALOG /SIGNAL_FOLDER=ENVELOPE /SIGNAL_NAMES=::EMG_SIGNAL_LIST /RESULT_TYPES=DERIVED /RESULT_FOLDERS=EMG_NORM_TEMP /RESULT_NAME= /APPLY_AS_SUFFIX_TO_SIGNAL_NAME=TRUE ; ! Loop over every sequence For_Each /ITERATION_PARAMETER_NAME=SEQUENCE_CURRENT ! /ITERATION_PARAMETER_COUNT_NAME= /ITEMS=::SEQUENCE_COUNT ; ! Define the "current" sequence as TEMP_CYCLE Event_Define_Event_Sequence /EVENT_SEQUENCE_NAME=TEMP_CYCLE /EVENT_SEQUENCE=&::SIDE&CYCLE_SEQUENCE ! /EXCLUDE_EVENTS= ! /INSIDE_OF_SEQUENCE= ! /OFFSET_FROM_START= ! /OFFSET_FROM_END= ! /OFFSET_BY=PERCENT /EVENT_SEQUENCE_INSTANCE=::SEQUENCE_CURRENT ; ! Loop over every EMG Signal For_Each /ITERATION_PARAMETER_NAME=EMG_SIGNAL_CURRENT ! /ITERATION_PARAMETER_COUNT_NAME= /ITEMS=::EMG_SIGNAL_LIST ; ! For all frames during the current cycle, ! set the values to the maximum of the EMG signal Set_Data_To_New_Values /SIGNAL_TYPES=DERIVED /SIGNAL_FOLDER=EMG_NORM_TEMP /SIGNAL_NAMES=::EMG_SIGNAL_CURRENT ! /SIGNAL_COMPONENTS=ALL_COMPONENTS /RESULT_TYPES=DERIVED /RESULT_FOLDERS=EMG_NORM_TEMP /RESULT_SUFFIX= /EVENT_SEQUENCE=TEMP_CYCLE ! /EXCLUDE_EVENTS= ! /START_FRAME= ! /END_FRAME= ! /USE_POINT_RATE=TRUE /REPLACEMENT_VALUES=METRIC_MAXIMUM(ANALOG::ENVELOPE::&::EMG_SIGNAL_CURRENT&,EVENT_LABEL::SEQUENCE::TEMP_CYCLE) ! /THRESHOLD_HIGH=NO_DATA ! /THRESHOLD_LOW=NO_DATA ! /SET_DATA_AT_SINGLE_EVENT=FALSE ; End_For_Each /ITERATION_PARAMETER_NAME=EMG_SIGNAL_CURRENT ; End_For_Each /ITERATION_PARAMETER_NAME=SEQUENCE_CURRENT ; ! --------------------------------------------------------------------- ! Normalize EMG Signal ! --------------------------------------------------------------------- ! Divide the EMG signals by the temporary signal above For_Each /ITERATION_PARAMETER_NAME=EMG_SIGNAL_CURRENT ! /ITERATION_PARAMETER_COUNT_NAME= /ITEMS=::EMG_SIGNAL_LIST ; Evaluate_Expression /EXPRESSION=ANALOG::ENVELOPE::&::EMG_SIGNAL_CURRENT& / DERIVED::EMG_NORM_TEMP::&::EMG_SIGNAL_CURRENT& ! /SIGNAL_TYPES= ! /SIGNAL_FOLDER= ! /SIGNAL_NAMES= /RESULT_TYPES=DERIVED /RESULT_FOLDERS=EMG_NORM /RESULT_NAME=&::EMG_SIGNAL_CURRENT& ! /APPLY_AS_SUFFIX_TO_SIGNAL_NAME=FALSE ; End_For_Each /ITERATION_PARAMETER_NAME=EMG_SIGNAL_CURRENT ; End_For_Each /ITERATION_PARAMETER_NAME=SIDE ;
Calling Example Meta-Command
Once the example Meta-Command from the download is placed in your Meta-Command folder, you can call the command using the following syntax:
EMG_Norm_Gait_Cycle /EMG_INPUT_FOLDER=ENVELOPE /EMG_OUTPUT_FOLDER=EMG_NORM /R_EMG_SIGNAL_LIST=EMG_A+EMG_B+EMG_C /R_EVENT_SEQUENCE=RHS+RTO /L_EMG_SIGNAL_LIST=EMG_A_L+EMG_B_L+EMG_C_L /L_EVENT_SEQUENCE=LHS+LTO ;
- EMG_INPUT_FOLDER should be the EMG signals you want to normalized
- EMG_OUTPUT_FOLDER should be the resulting EMG folder for the normalized signals
- R_EMG_SIGNAL_LIST the list of right side EMG signals to normalize to the right gait cycle
- R_EVENT_SEQUENCE events which indicate the right gait cycle (this example normalizes to stance, but you probably want to normalize to the entire gait cycle)
- L_EMG_SIGNAL_LIST the list of left side EMG signals to normalize to the left gait cycle
- R_EVENT_SEQUENCE events which indicate the left gait cycle (this example normalizes to stance, but you probably want to normalize to the entire gait cycle)
visual3d/documentation/emg/processing/normalize_emg_to_mvc.txt · Last modified: 2024/07/17 11:45 by sgranger