====== 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 ;