-----
    Brief
    -----
    Python implementation of Burst detection algorithm using Teager Kaiser Energy Operator.

    -----------
    Description
    -----------
    Activation events in EMG readings correspond to an increase of muscular activity, namely, from inaction to action.
    These events are characterised by an increase in electric potential that returns to the initial values when the
    muscle returns to a state of inaction.

    This function detects activation events using the Teager Kaiser Energy Operator.

    ----------
    Parameters
    ----------
    emg_signal : list
        List of EMG acquired samples.

    sample_rate : int
        Sampling frequency.

    smooth_level : number
        Defines a percentage proportional to the smoothing level, i.e. the bigger this value is,
        the more smoothed is the signal.

    threshold_level : number
        Specification of the single threshold position, used for distinguishing between activation
        (above) and inactivation samples (below).

    time_units : boolean
        If True this function will return the Burst begin and end positions in seconds.

    volts : boolean
        If True, then the conversion of raw units to mV will be done. Resolution need to be
        specified.

    resolution : int
        Selected resolution for data acquisition.

    device : str
        Specification of the device category.

    plot_result : boolean
        If True it will be presented a graphical representation of the detected burst in the EMG
        signal.

    Returns
    -------
    out : bursts begin (ndarray), bursts end (ndarray)
        Begin and end of bursts (sample number or time instant in seconds).

    smooth_signal: list
        It is returned the smoothed EMG signal (after the processing steps intended to simplify the
        signal).

    threshold_level: float
        The value of the detection threshold used to locate the begin and end of each muscular
        activation period.

def detect_emg_activations(emg_signal, sample_rate, smooth_level=20, threshold_level=10,
                           time_units=False, volts=False, resolution=None, device="biosignalsplux",
                           plot_result=False):
    """
    -----
    Brief
    -----
    Python implementation of Burst detection algorithm using Teager Kaiser Energy Operator.

    -----------
    Description
    -----------
    Activation events in EMG readings correspond to an increase of muscular activity, namely, from inaction to action.
    These events are characterised by an increase in electric potential that returns to the initial values when the
    muscle returns to a state of inaction.

    This function detects activation events using the Teager Kaiser Energy Operator.

    ----------
    Parameters
    ----------
    emg_signal : list
        List of EMG acquired samples.

    sample_rate : int
        Sampling frequency.

    smooth_level : number
        Defines a percentage proportional to the smoothing level, i.e. the bigger this value is,
        the more smoothed is the signal.

    threshold_level : number
        Specification of the single threshold position, used for distinguishing between activation
        (above) and inactivation samples (below).

    time_units : boolean
        If True this function will return the Burst begin and end positions in seconds.

    volts : boolean
        If True, then the conversion of raw units to mV will be done. Resolution need to be
        specified.

    resolution : int
        Selected resolution for data acquisition.

    device : str
        Specification of the device category.

    plot_result : boolean
        If True it will be presented a graphical representation of the detected burst in the EMG
        signal.

    Returns
    -------
    out : bursts begin (ndarray), bursts end (ndarray)
        Begin and end of bursts (sample number or time instant in seconds).

    smooth_signal: list
        It is returned the smoothed EMG signal (after the processing steps intended to simplify the
        signal).

    threshold_level: float
        The value of the detection threshold used to locate the begin and end of each muscular
        activation period.
    """

    if volts is True:
        if resolution is not None:
            emg_signal = raw_to_phy("EMG", device, emg_signal, resolution, option="mV")
            units = "mV"
        else:
            raise RuntimeError(
                "For converting raw units to mV is mandatory the specification of acquisition "
                "resolution.")
    else:
        units = "Input Units"

    if time_units is True:
        time_units_str = "Time (s)"
        time = numpy.linspace(0, len(emg_signal) / sample_rate, len(emg_signal))
    else:
        time = numpy.linspace(0, len(emg_signal) - 1, len(emg_signal))
        time_units_str = "Sample Number"

    # ----------------------------------- Baseline Removal -----------------------------------------
    pre_pro_signal = numpy.array(emg_signal) - numpy.average(emg_signal)

    # ------------------------------------ Signal Filtering ----------------------------------------
    low_cutoff = 10  # Hz
    high_cutoff = 300  # Hz

    # Application of the signal to the filter.
    pre_pro_signal = _butter_bandpass_filter(pre_pro_signal, low_cutoff, high_cutoff, sample_rate)

    # ------------------------------ Application of TKEO Operator ----------------------------------
    tkeo = []
    for i, signal_sample in enumerate(pre_pro_signal):
        if i in (0, len(pre_pro_signal) - 1):
            tkeo.append(signal_sample)
        else:
            tkeo.append(numpy.power(signal_sample, 2) - (pre_pro_signal[i + 1] *
                                                         pre_pro_signal[i - 1]))

    # Smoothing level - Size of sliding window used during the moving average process (a function
    # of sampling frequency)
    smoothing_level = int((smooth_level / 100) * sample_rate)

    # --------------------------------- Signal Rectification ---------------------------------------
    rect_signal = numpy.absolute(tkeo)

    # ------------------------------ First Moving Average Filter -----------------------------------
    rect_signal = _moving_average(rect_signal, sample_rate / 10)

    # -------------------------------- Second Smoothing Phase --------------------------------------
    smooth_signal = []
    for i in range(0, len(rect_signal)):
        if smoothing_level < i < len(rect_signal) - smoothing_level:
            smooth_signal.append(numpy.mean(rect_signal[i - smoothing_level:i + smoothing_level]))
        else:
            smooth_signal.append(0)

    # ----------------------------------- Threshold -----------------------------------------------
    avg_pre_pro_signal = numpy.average(pre_pro_signal)
    std_pre_pro_signal = numpy.std(pre_pro_signal)

    threshold_level = avg_pre_pro_signal + _thres_norm_reg(threshold_level, smooth_signal,
                                                           pre_pro_signal) * std_pre_pro_signal

    # Generation of a square wave reflecting the activation and inactivation periods.
    binary_signal = []
    for i in range(0, len(time)):
        if smooth_signal[i] >= threshold_level:
            binary_signal.append(1)
        else:
            binary_signal.append(0)

    # ------------------------------ Begin and End of Bursts --------------------------------------
    diff_signal = numpy.diff(binary_signal)
    act_begin = numpy.where(diff_signal == 1)[0]
    act_end = numpy.where(diff_signal == -1)[0]

    if time_units is True:
        time_begin = numpy.array(time)[act_begin]
        time_end = numpy.array(time)[act_end]
    else:
        time_begin = act_begin
        time_end = act_end

    # If plot is invoked by plot_result flag, then a graphical representation of the R peaks is
    # presented to the user.
    if plot_result is True:
        plot([list(time), list(time)], [list(emg_signal), list(numpy.array(binary_signal) *
                                                               numpy.max(emg_signal))],
             yAxisLabel=["Data Samples (" + units + ")"] * 2,
             x_axis_label=time_units_str, legend=["EMG Signal", "Activation Signal"])

    return time_begin, time_end, smooth_signal, threshold_level