Ejemplo n.º 1
0
def _loop_once():
    '''Run the main loop once
    This uses the global variables from setup and start, and adds a set of global variables
    '''
    global parser, args, config, r, response, patch, monitor, debug, ft_host, ft_port, ft_input, ft_output
    global timeout, hdr_input, start, window, downsample, differentiate, integrate, rectify, smoothing, reference, default_scale, scale_lowpass, scale_highpass, scale_notchfilter, offset_lowpass, offset_highpass, offset_notchfilter, scale_filterorder, scale_notchquality, offset_filterorder, offset_notchquality, previous, differentiate_zi, integrate_zi, begsample, endsample
    global dat_input, dat_output, highpassfilter, lowpassfilter, filterorder, change, b, a, zi, notchfilter, notchquality, nb, na, nzi, window_new, t
    global montage_in, montage_out

    monitor.loop()

    # determine when we start polling for available data
    start = time.time()

    while endsample > hdr_input.nSamples - 1:
        # wait until there is enough data
        time.sleep(patch.getfloat('general', 'delay'))
        hdr_input = ft_input.getHeader()
        if (hdr_input.nSamples - 1) < (endsample - window):
            raise RuntimeError("buffer reset detected")
        if (time.time() - start) > timeout:
            raise RuntimeError("timeout while waiting for data")

    # determine the start of the actual processing
    start = time.time()

    dat_input = ft_input.getData([begsample, endsample]).astype(np.float32)
    dat_output = dat_input

    monitor.trace(
        "------------------------------------------------------------")
    monitor.trace("read        " + str(window) + " samples in " +
                  str((time.time() - start) * 1000) + " ms")

    # Online bandpass filtering
    highpassfilter = patch.getfloat('processing',
                                    'highpassfilter',
                                    default=None)
    if highpassfilter != None:
        highpassfilter = EEGsynth.rescale(highpassfilter,
                                          slope=scale_highpass,
                                          offset=offset_highpass)
    lowpassfilter = patch.getfloat('processing', 'lowpassfilter', default=None)
    if lowpassfilter != None:
        lowpassfilter = EEGsynth.rescale(lowpassfilter,
                                         slope=scale_lowpass,
                                         offset=offset_lowpass)
    filterorder = patch.getfloat('processing',
                                 'filterorder',
                                 default=int(2 * hdr_input.fSample))
    if filterorder != None:
        filterorder = EEGsynth.rescale(filterorder,
                                       slope=scale_filterorder,
                                       offset=offset_filterorder)

    change = False
    change = monitor.update('highpassfilter', highpassfilter) or change
    change = monitor.update('lowpassfilter', lowpassfilter) or change
    change = monitor.update('filterorder', filterorder) or change
    if change:
        # update the filter parameters
        filterorder = int(filterorder)  # ensure it is an integer
        filterorder = filterorder + (filterorder % 2 == 0)  # ensure it is odd
        b, a, zi = EEGsynth.initialize_online_filter(hdr_input.fSample,
                                                     highpassfilter,
                                                     lowpassfilter,
                                                     filterorder,
                                                     dat_output,
                                                     axis=0)

    if not (highpassfilter is None) or not (lowpassfilter is None):
        # apply the filter to the data
        dat_output, zi = EEGsynth.online_filter(b,
                                                a,
                                                dat_output,
                                                axis=0,
                                                zi=zi)
        monitor.debug("filtered    ", window, "samples in",
                      (time.time() - start) * 1000, "ms")

    # Online notch filtering
    notchfilter = patch.getfloat('processing', 'notchfilter', default=None)
    if notchfilter != None:
        notchfilter = EEGsynth.rescale(notchfilter,
                                       slope=scale_notchfilter,
                                       offset=offset_notchfilter)
    notchquality = patch.getfloat('processing', 'notchquality', default=25)
    if notchquality != None:
        notchquality = EEGsynth.rescale(notchquality,
                                        slope=scale_notchquality,
                                        offset=offset_notchquality)

    change = False
    change = monitor.update('notchfilter', notchfilter) or change
    change = monitor.update('notchquality', notchquality) or change
    if change:
        # update the filter parameters
        nb, na, nzi = EEGsynth.initialize_online_notchfilter(hdr_input.fSample,
                                                             notchfilter,
                                                             notchquality,
                                                             dat_output,
                                                             axis=0)

    if not (notchfilter is None):
        # apply the filter to the data
        dat_output, nzi = EEGsynth.online_filter(nb,
                                                 na,
                                                 dat_output,
                                                 axis=0,
                                                 zi=nzi)
        monitor.debug("notched     ", window, "samples in",
                      (time.time() - start) * 1000, "ms")

    # Differentiate
    if differentiate:
        dat_output, d_zi = EEGsynth.online_filter([1, -1],
                                                  1,
                                                  dat_output,
                                                  axis=0,
                                                  zi=differentiate_zi)

    # Integrate
    if integrate:
        dat_output, i_zi = EEGsynth.online_filter(1, [1, -1],
                                                  dat_output,
                                                  axis=0,
                                                  zi=integrate_zi)

    # Rectifying
    if rectify:
        dat_output = np.absolute(dat_output)

    # Smoothing
    if not (smoothing is None):
        for t in range(window):
            dat_output[t, :] = smoothing * dat_output[t, :] + (
                1. - smoothing) * previous
            previous = copy(dat_output[t, :])
        monitor.debug("smoothed    ", window_new, "samples in",
                      (time.time() - start) * 1000, "ms")

    # Downsampling
    if not (downsample is None):
        # do not apply an anti aliassing filter, the data segment is probably too short for that
        dat_output = decimate(dat_output,
                              downsample,
                              n=0,
                              ftype='iir',
                              axis=0,
                              zero_phase=True)
        window_new = int(window / downsample)
        monitor.debug("downsampled ", window, "samples in",
                      (time.time() - start) * 1000, "ms")
    else:
        window_new = window

    # Re-referencing
    if reference == 'median':
        dat_output -= repmat(np.nanmedian(dat_output, axis=1),
                             dat_output.shape[1], 1).T
        monitor.debug("rereferenced (median)", window_new, "samples in",
                      (time.time() - start) * 1000, "ms")
    elif reference == 'average':
        dat_output -= repmat(np.nanmean(dat_output, axis=1),
                             dat_output.shape[1], 1).T
        monitor.debug("rereferenced (average)", window_new, "samples in",
                      (time.time() - start) * 1000, "ms")
    elif reference == 'montage':
        monitor.debug("applying montage")
        for i, name in enumerate(montage_out):
            montage_in[i] = patch.getfloat('montage', name, multiple=True)
        dat_output = np.matmul(dat_output,
                               np.transpose(np.array(montage_in), (1, 0)))
        print("Data dimensions after montage:", dat_output.shape)
    else:
        monitor.debug("No rereferencing or montage applied")

    # write the data to the output buffer
    ft_output.putData(dat_output.astype(np.float32))

    monitor.info("preprocessed " + str(window_new) + " samples in " +
                 str((time.time() - start) * 1000) + " ms")
    monitor.trace("wrote       " + str(window_new) + " samples in " +
                  str((time.time() - start) * 1000) + " ms")

    # increment the counters for the next loop
    begsample += window
    endsample += window
Ejemplo n.º 2
0
def _loop_once():
    '''Run the main loop once
    This uses the global variables from setup and start, and adds a set of global variables
    '''
    global parser, args, config, r, response, patch, monitor, debug, ft_host, ft_port, ft_input, ft_output
    global timeout, hdr_input, start, sample_rate, f_shift, f_offset, f_order, window, sideband, left, right, scaling, scaling_method, scale_scaling, offset_scaling, default_scale, scale_lowpass, scale_highpass, offset_lowpass, offset_highpass, scale_filterorder, offset_filterorder, hdr_output, nInput, nOutput, begsample, endsample, dat_output, left_f, left_b, left_a, left_zi, right_f, right_b, right_a, right_zi, i, highpass, lowpass
    global dat_input, begtime, endtime, tim_input, tim_output, chan, vec_output, highpassfilter, lowpassfilter, filterorder, change, b, a, zi, duration, desired

    monitor.loop()

    # determine when we start polling for available data
    start = time.time()

    while endsample > hdr_input.nSamples - 1:
        # wait until there is enough data
        time.sleep(patch.getfloat('general', 'delay'))
        hdr_input = ft_input.getHeader()
        if hdr_input.nSamples < begsample:
            raise RuntimeError("buffer reset detected")
        if (time.time() - start) > timeout:
            raise RuntimeError("timeout while waiting for data")

    # get the input data
    dat_input = ft_input.getData([begsample, endsample]).astype(np.double)
    dat_output = np.zeros((nOutput, hdr_output.nChannels))

    # construct a time vector for input and output
    begtime = float(begsample) / hdr_input.fSample
    endtime = float(endsample + 1) / hdr_input.fSample
    tim_input = np.linspace(begtime, endtime, nInput, endpoint=False)
    tim_output = np.linspace(begtime, endtime, nOutput, endpoint=False)

    for chan, i in zip(left, list(range(len(left)))):
        # interpolate each channel onto the output sampling rate
        vec_output = np.interp(tim_output, tim_input, dat_input[:, chan - 1])
        # multiply with the modulating signal
        vec_output *= np.cos(tim_output * left_f[i] * 2 * np.pi)
        if highpass != None or lowpass != None:
            # apply the filter to remove one sideband
            vec_output, left_zi[i] = EEGsynth.online_filter(left_b[i],
                                                            left_a[i],
                                                            vec_output,
                                                            zi=left_zi[i])
        # add it to the left-channel output
        dat_output[:, 0] += vec_output

    for chan, i in zip(right, list(range(len(right)))):
        # interpolate each channel onto the output sampling rate
        vec_output = np.interp(tim_output, tim_input, dat_input[:, chan - 1])
        # multiply with the modulating signal
        vec_output *= np.cos(tim_output * right_f[i] * 2 * np.pi)
        if highpass != None or lowpass != None:
            # apply the filter to remove one sideband
            vec_output, right_zi[i] = EEGsynth.online_filter(right_b[i],
                                                             right_a[i],
                                                             vec_output,
                                                             zi=right_zi[i])
        # add it to the right-channel output
        dat_output[:, 1] += vec_output

    # Online filtering
    highpassfilter = patch.getfloat('processing',
                                    'highpassfilter',
                                    default=None)
    if highpassfilter != None:
        highpassfilter = EEGsynth.rescale(highpassfilter,
                                          slope=scale_highpass,
                                          offset=offset_highpass)
    lowpassfilter = patch.getfloat('processing', 'lowpassfilter', default=None)
    if lowpassfilter != None:
        lowpassfilter = EEGsynth.rescale(lowpassfilter,
                                         slope=scale_lowpass,
                                         offset=offset_lowpass)
    filterorder = patch.getfloat('processing',
                                 'filterorder',
                                 default=int(2 * hdr_input.fSample))
    if filterorder != None:
        filterorder = EEGsynth.rescale(filterorder,
                                       slope=scale_filterorder,
                                       offset=offset_filterorder)

    change = False
    change = monitor.update('highpassfilter', highpassfilter) or change
    change = monitor.update('lowpassfilter', lowpassfilter) or change
    change = monitor.update('filterorder', filterorder) or change
    if change:
        # update the filter parameters
        filterorder = int(filterorder)  # ensure it is an integer
        filterorder = filterorder + (filterorder % 2 == 0)  # ensure it is odd
        b, a, zi = EEGsynth.initialize_online_filter(hdr_input.fSample,
                                                     highpassfilter,
                                                     lowpassfilter,
                                                     filterorder,
                                                     dat_output,
                                                     axis=0)

    if not (highpassfilter is None) or not (lowpassfilter is None):
        # apply the filter to the data
        dat_output, zi = EEGsynth.online_filter(b,
                                                a,
                                                dat_output,
                                                axis=0,
                                                zi=zi)

    # normalize for the number of channels
    dat_output /= hdr_input.nChannels

    scaling = patch.getfloat('signal', 'scaling', default=1)
    scaling = EEGsynth.rescale(scaling,
                               slope=scale_scaling,
                               offset=offset_scaling)
    if scaling_method == 'multiply':
        dat_output *= scaling
    elif scaling_method == 'divide':
        dat_output /= scaling
    elif scaling_method == 'db':
        dat_output *= np.power(10, scaling / 20)

    # write the data to the output buffer
    ft_output.putData(dat_output.astype(np.float32))

    # compute the duration and desired number of output samples
    duration = time.time() - start
    desired = duration * sample_rate

    # update the number of output samples for the next iteration
    #    if nOutput > desired:
    #        nOutput /= 1.002
    #    elif nOutput < desired:
    #        nOutput *= 1.002
    #    nOutput = int(round(nOutput))

    monitor.info("wrote", nInput, "->", nOutput, "samples in", duration * 1000,
                 "ms")

    # shift to the next block of data
    begsample += nInput
    endsample += nInput

    # there should not be any local variables in this function, they should all be global
    if len(locals()):
        print('LOCALS: ' + ', '.join(locals().keys()))
Ejemplo n.º 3
0
    dat_input = ft_input.getData([begsample, endsample])
    dat_output = np.zeros((nOutput,hdr_output.nChannels))

    # construct a time vector for input and output
    begtime = float(begsample  ) / hdr_input.fSample
    endtime = float(endsample+1) / hdr_input.fSample
    tim_input = np.linspace(begtime, endtime, nInput, endpoint=False)
    tim_output = np.linspace(begtime, endtime, nOutput, endpoint=False)

    for chan, i in zip(left, list(range(len(left)))):
        # interpolate each channel onto the output sampling rate
        vec_output = np.interp(tim_output, tim_input, dat_input[:, chan-1])
        # multiply with the modulating signal
        vec_output *= np.cos(tim_output * left_f[i] * 2 * np.pi)
        # apply the filter to remove one sideband
        vec_output, left_zi[i] = EEGsynth.online_filter(left_b[i], left_a[i], vec_output, zi=left_zi[i])
        # add it to the output
        dat_output[:,0] += vec_output

    for chan, i in zip(right, list(range(len(right)))):
        # interpolate each channel onto the output sampling rate
        vec_output = np.interp(tim_output, tim_input, dat_input[:, chan-1])
        # multiply with the modulating signal
        vec_output *= np.cos(tim_output * right_f[i] * 2 * np.pi)
        # apply the filter to remove one sideband
        vec_output, right_zi[i] = EEGsynth.online_filter(right_b[i], right_a[i], vec_output, zi=right_zi[i])
        # add it to the output
        dat_output[:,1] += vec_output

    # normalize for the number of channels
    dat_output /= hdr_input.nChannels
Ejemplo n.º 4
0
    dat_input = ft_input.getData([begsample, endsample])
    dat_output = np.zeros((nOutput,hdr_output.nChannels))

    # construct a time vector for input and output
    begtime = float(begsample  ) / hdr_input.fSample
    endtime = float(endsample+1) / hdr_input.fSample
    tim_input = np.linspace(begtime, endtime, nInput, endpoint=False)
    tim_output = np.linspace(begtime, endtime, nOutput, endpoint=False)

    for chan, i in zip(left, range(len(left))):
        # interpolate each channel onto the output sampling rate
        vec_output = np.interp(tim_output, tim_input, dat_input[:, chan-1])
        # multiply with the modulating signal
        vec_output *= np.cos(tim_output * left_f[i] * 2 * np.pi)
        # apply the filter to remove one sideband
        vec_output, left_zi[i] = EEGsynth.online_filter(left_b[i], left_a[i], vec_output, zi=left_zi[i])
        # add it to the output
        dat_output[:,0] += vec_output

    for chan, i in zip(right, range(len(right))):
        # interpolate each channel onto the output sampling rate
        vec_output = np.interp(tim_output, tim_input, dat_input[:, chan-1])
        # multiply with the modulating signal
        vec_output *= np.cos(tim_output * right_f[i] * 2 * np.pi)
        # apply the filter to remove one sideband
        vec_output, right_zi[i] = EEGsynth.online_filter(right_b[i], right_a[i], vec_output, zi=right_zi[i])
        # add it to the output
        dat_output[:,1] += vec_output

    # normalize for the number of channels
    dat_output /= hdr_input.nChannels
Ejemplo n.º 5
0
    # construct a time vector for input and output
    begtime = float(begsample) / hdr_input.fSample
    endtime = float(endsample + 1) / hdr_input.fSample
    tim_input = np.linspace(begtime, endtime, nInput, endpoint=False)
    tim_output = np.linspace(begtime, endtime, nOutput, endpoint=False)

    for chan, i in zip(left, list(range(len(left)))):
        # interpolate each channel onto the output sampling rate
        vec_output = np.interp(tim_output, tim_input, dat_input[:, chan - 1])
        # multiply with the modulating signal
        vec_output *= np.cos(tim_output * left_f[i] * 2 * np.pi)
        if highpass != None or lowpass != None:
            # apply the filter to remove one sideband
            vec_output, left_zi[i] = EEGsynth.online_filter(left_b[i],
                                                            left_a[i],
                                                            vec_output,
                                                            zi=left_zi[i])
        # add it to the left-channel output
        dat_output[:, 0] += vec_output

    for chan, i in zip(right, list(range(len(right)))):
        # interpolate each channel onto the output sampling rate
        vec_output = np.interp(tim_output, tim_input, dat_input[:, chan - 1])
        # multiply with the modulating signal
        vec_output *= np.cos(tim_output * right_f[i] * 2 * np.pi)
        if highpass != None or lowpass != None:
            # apply the filter to remove one sideband
            vec_output, right_zi[i] = EEGsynth.online_filter(right_b[i],
                                                             right_a[i],
                                                             vec_output,
                                                             zi=right_zi[i])
Ejemplo n.º 6
0
    if highpassfilter != None:
        highpassfilter = EEGsynth.rescale(highpassfilter, slope=scale_highpass, offset=offset_highpass)
    lowpassfilter = patch.getfloat('processing', 'lowpassfilter', default=None)
    if lowpassfilter != None:
        lowpassfilter = EEGsynth.rescale(lowpassfilter, slope=scale_lowpass, offset=offset_lowpass)

    change = False
    change = show_change('highpassfilter',  highpassfilter) or change
    change = show_change('lowpassfilter',   lowpassfilter)  or change
    if change:
        # update the filter parameters
        b, a, zi = EEGsynth.initialize_online_filter(hdr_input.fSample, highpassfilter, lowpassfilter, filterorder, dat_output, axis=0)

    if not(highpassfilter is None) or not(lowpassfilter is None):
        # apply the filter to the data
        dat_output, zi = EEGsynth.online_filter(b, a, dat_output, axis=0, zi=zi)
        if debug>1:
            print("filtered    ", window, "samples in", (time.time()-start)*1000, "ms")

    # Downsampling
    if not(downsample is None):
        dat_output = decimate(dat_output, downsample, ftype='iir', axis=0, zero_phase=True)
        window_new = int(window / downsample)
        if debug>1:
            print("downsampled ", window, "samples in", (time.time()-start)*1000, "ms")
    else:
        window_new = window

    # Smoothing
    if not(smoothing is None):
        for t in range(window):
Ejemplo n.º 7
0
    if change:
        # update the filter parameters
        filterorder = int(filterorder)  # ensure it is an integer
        filterorder = filterorder + (filterorder % 2 == 0)  # ensure it is odd
        b, a, zi = EEGsynth.initialize_online_filter(hdr_input.fSample,
                                                     highpassfilter,
                                                     lowpassfilter,
                                                     filterorder,
                                                     dat_output,
                                                     axis=0)

    if not (highpassfilter is None) or not (lowpassfilter is None):
        # apply the filter to the data
        dat_output, zi = EEGsynth.online_filter(b,
                                                a,
                                                dat_output,
                                                axis=0,
                                                zi=zi)
        if debug > 1:
            print("filtered    ", window, "samples in",
                  (time.time() - start) * 1000, "ms")

    # Online notch filtering
    notchfilter = patch.getfloat('processing', 'notchfilter', default=None)
    if notchfilter != None:
        notchfilter = EEGsynth.rescale(notchfilter,
                                       slope=scale_notchfilter,
                                       offset=offset_notchfilter)
    notchquality = patch.getfloat('processing', 'notchquality', default=25)
    if notchquality != None:
        notchquality = EEGsynth.rescale(notchquality,