コード例 #1
0
ファイル: plotsignal.py プロジェクト: licy07/eegsynth
def _loop_once():
    '''Update the main figure 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
    global channels, winx, winy, winwidth, winheight, window, clipsize, stepsize, lrate, ylim, timeout, hdr_input, start, filtorder, filter, notch, app, win, timeplot, curve, curvemax, plotnr, channr, timer, begsample, endsample
    global dat, timeaxis

    monitor.loop()

    hdr_input = ft_input.getHeader()
    if (hdr_input.nSamples - 1) < endsample:
        monitor.info("buffer reset detected")
        begsample = -1
        while begsample < 0:
            hdr_input = ft_input.getHeader()
            begsample = hdr_input.nSamples - window
            endsample = hdr_input.nSamples - 1

    # get the last available data
    begsample = (
        hdr_input.nSamples - window
    )  # the clipsize will be removed from both sides after filtering
    endsample = (hdr_input.nSamples - 1)

    monitor.info("reading from sample %d to %d" % (begsample, endsample))

    dat = ft_input.getData([begsample, endsample]).astype(np.double)

    # demean the data before filtering to reduce edge artefacts and to center timecourse
    if patch.getint('arguments', 'demean', default=1):
        dat = detrend(dat, axis=0, type='constant')

    # detrend the data before filtering to reduce edge artefacts and to center timecourse
    # this is rather slow, hence the default is not to detrend
    if patch.getint('arguments', 'detrend', default=0):
        dat = detrend(dat, axis=0, type='linear')

    # apply the user-defined filtering
    if not np.isnan(filter[0]) and not np.isnan(filter[1]):
        dat = EEGsynth.butter_bandpass_filter(dat.T, filter[0], filter[1],
                                              int(hdr_input.fSample),
                                              filtorder).T
    elif not np.isnan(filter[1]):
        dat = EEGsynth.butter_lowpass_filter(dat.T, filter[1],
                                             int(hdr_input.fSample),
                                             filtorder).T
    elif not np.isnan(filter[0]):
        dat = EEGsynth.butter_highpass_filter(dat.T, filter[0],
                                              int(hdr_input.fSample),
                                              filtorder).T
    if not np.isnan(notch):
        dat = EEGsynth.notch_filter(dat.T, notch, hdr_input.fSample).T

    # remove the filter padding
    if clipsize > 0:
        dat = dat[clipsize:-clipsize, :]

    for plotnr, channr in enumerate(channels):

        # time axis
        timeaxis = np.linspace(-(window - 2 * clipsize) / hdr_input.fSample, 0,
                               len(dat))

        # update timecourses
        curve[plotnr].setData(timeaxis, dat[:, channr - 1])

        if len(ylim) == 2:
            # set the vertical scale to the user-specified limits
            timeplot[plotnr].setYRange(ylim[0], ylim[1])
        else:
            # slowly adapt the vertical scale to the running max
            if curvemax[plotnr] == None:
                curvemax[plotnr] = max(abs(dat[:, channr - 1]))
            else:
                curvemax[plotnr] = (1 -
                                    lrate) * curvemax[plotnr] + lrate * max(
                                        abs(dat[:, channr - 1]))
            timeplot[plotnr].setYRange(-curvemax[plotnr], curvemax[plotnr])
コード例 #2
0
def _loop_once():
    '''Update the main figure 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, ft_host, ft_port, ft_input
    global timeout, hdr_input, start, channels, window, clipsize, stepsize, historysize, lrate, ylim, scale_red, scale_blue, offset_red, offset_blue, winx, winy, winwidth, winheight, prefix, numhistory, freqaxis, history, showred, showblue, filtorder, filter, notch, app, win, text_redleft_curr, text_redright_curr, text_blueleft_curr, text_blueright_curr, text_redleft_hist, text_redright_hist, text_blueleft_hist, text_blueright_hist, freqplot_curr, freqplot_hist, spect_curr, spect_hist, redleft_curr, redright_curr, blueleft_curr, blueright_curr, redleft_hist, redright_hist, blueleft_hist, blueright_hist, fft_curr, fft_hist, specmax_curr, specmin_curr, specmax_hist, specmin_hist, plotnr, channr, timer, begsample, endsample, taper
    global dat, arguments_freqrange, freqrange, redfreq, redwidth, bluefreq, bluewidth

    monitor.loop()

    hdr_input = ft_input.getHeader()
    if (hdr_input.nSamples-1)<endsample:
        monitor.info("buffer reset detected")
        begsample = -1
        while begsample < 0:
            hdr_input = ft_input.getHeader()
            begsample = hdr_input.nSamples - window
            endsample = hdr_input.nSamples - 1

    # get the last available data
    begsample = (hdr_input.nSamples - window)  # the clipsize will be removed from both sides after filtering
    endsample = (hdr_input.nSamples - 1)

    monitor.info("reading from sample %d to %d" % (begsample, endsample))

    dat = ft_input.getData([begsample, endsample]).astype(np.double)

    # demean the data to prevent spectral leakage
    if patch.getint('arguments', 'demean', default=1):
        dat = detrend(dat, axis=0, type='constant')

    # detrend the data to prevent spectral leakage
    # this is rather slow, hence the default is not to detrend
    if patch.getint('arguments', 'detrend', default=0):
        dat = detrend(dat, axis=0, type='linear')

    # apply the user-defined filtering
    if not np.isnan(filter[0]) and not np.isnan(filter[1]):
        dat = EEGsynth.butter_bandpass_filter(dat.T, filter[0], filter[1], int(hdr_input.fSample), filtorder).T
    elif not np.isnan(filter[1]):
        dat = EEGsynth.butter_lowpass_filter(dat.T, filter[1], int(hdr_input.fSample), filtorder).T
    elif not np.isnan(filter[0]):
        dat = EEGsynth.butter_highpass_filter(dat.T, filter[0], int(hdr_input.fSample), filtorder).T
    if not np.isnan(notch):
        dat = EEGsynth.notch_filter(dat.T, notch, hdr_input.fSample).T

    # remove the filter padding
    if clipsize > 0:
        dat = dat[clipsize:-clipsize,:]

    # taper the data
    dat = dat * taper[:, np.newaxis]

    # shift the FFT history by one step
    history = np.roll(history, 1, axis=2)

    for plotnr, channr in enumerate(channels):

        # estimate the absolute FFT amplitude at the current moment
        fft_curr[plotnr] = abs(fft(dat[:, channr-1]))

        # update the FFT history with the current estimate
        history[plotnr, :, numhistory - 1] = fft_curr[plotnr]
        fft_hist = np.mean(history, axis=2)

        # user-selected frequency band
        arguments_freqrange = patch.getfloat('arguments', 'freqrange', multiple=True)
        freqrange = np.greater(freqaxis, arguments_freqrange[0]) & np.less_equal(freqaxis, arguments_freqrange[1])

        # adapt the vertical scale to the running mean of the min/max
        if specmax_curr[plotnr]==None:
            specmax_curr[plotnr] = max(fft_curr[plotnr][freqrange])
            specmin_curr[plotnr] = min(fft_curr[plotnr][freqrange])
            specmax_hist[plotnr] = max(fft_hist[plotnr][freqrange])
            specmin_hist[plotnr] = min(fft_hist[plotnr][freqrange])
        else:
            specmax_curr[plotnr] = (1 - lrate) * float(specmax_curr[plotnr]) + lrate * max(fft_curr[plotnr][freqrange])
            specmin_curr[plotnr] = (1 - lrate) * float(specmin_curr[plotnr]) + lrate * min(fft_curr[plotnr][freqrange])
            specmax_hist[plotnr] = (1 - lrate) * float(specmax_hist[plotnr]) + lrate * max(fft_hist[plotnr][freqrange])
            specmin_hist[plotnr] = (1 - lrate) * float(specmin_hist[plotnr]) + lrate * min(fft_hist[plotnr][freqrange])

        # update the axes
        freqplot_curr[plotnr].setXRange(arguments_freqrange[0], arguments_freqrange[1])
        freqplot_hist[plotnr].setXRange(arguments_freqrange[0], arguments_freqrange[1])
        if len(ylim)==2:
            # set the vertical scale to the user-specified limits
            freqplot_curr[plotnr].setYRange(ylim[0], ylim[1])
            freqplot_hist[plotnr].setYRange(ylim[0], ylim[1])
        else:
            # set the vertical scale to the user-specified limits
            freqplot_curr[plotnr].setYRange(specmin_curr[plotnr], specmax_curr[plotnr])
            freqplot_hist[plotnr].setYRange(specmin_hist[plotnr], specmax_hist[plotnr])

        # update the spectra
        spect_curr[plotnr].setData(freqaxis[freqrange], fft_curr[plotnr][freqrange])
        spect_hist[plotnr].setData(freqaxis[freqrange], fft_hist[plotnr][freqrange])

        # update the vertical plotted lines
        if showred:
            redfreq  = patch.getfloat('input', 'redfreq', default=10. / arguments_freqrange[1])
            redfreq  = EEGsynth.rescale(redfreq, slope=scale_red, offset=offset_red) * arguments_freqrange[1]
            redwidth = patch.getfloat('input', 'redwidth', default=1. / arguments_freqrange[1])
            redwidth = EEGsynth.rescale(redwidth, slope=scale_red, offset=offset_red) * arguments_freqrange[1]
            redleft_curr[plotnr].setData(x=[redfreq - redwidth, redfreq - redwidth], y=[specmin_curr[plotnr], specmax_curr[plotnr]])
            redright_curr[plotnr].setData(x=[redfreq + redwidth, redfreq + redwidth], y=[specmin_curr[plotnr], specmax_curr[plotnr]])
            redleft_hist[plotnr].setData(x=[redfreq - redwidth, redfreq - redwidth], y=[specmin_hist[plotnr], specmax_hist[plotnr]])
            redright_hist[plotnr].setData(x=[redfreq + redwidth, redfreq + redwidth], y=[specmin_hist[plotnr], specmax_hist[plotnr]])
            # update labels at the vertical lines
            text_redleft_curr.setText('%0.1f' % (redfreq - redwidth))
            text_redleft_curr.setPos(redfreq - redwidth, specmax_curr[0])
            text_redright_curr.setText('%0.1f' % (redfreq + redwidth))
            text_redright_curr.setPos(redfreq + redwidth, specmax_curr[0])
            text_redleft_hist.setText('%0.1f' % (redfreq - redwidth))
            text_redleft_hist.setPos(redfreq - redwidth, specmax_hist[0])
            text_redright_hist.setText('%0.1f' % (redfreq + redwidth))
            text_redright_hist.setPos(redfreq + redwidth, specmax_hist[0])
            # write the positions of the lines to Redis
            key = "%s.%s.%s" % (prefix, 'redband', 'low')
            patch.setvalue(key, redfreq - redwidth)
            key = "%s.%s.%s" % (prefix, 'redband', 'high')
            patch.setvalue(key, redfreq + redwidth)

        if showblue:
            bluefreq  = patch.getfloat('input', 'bluefreq', default=20. / arguments_freqrange[1])
            bluefreq  = EEGsynth.rescale(bluefreq, slope=scale_blue, offset=offset_blue) * arguments_freqrange[1]
            bluewidth = patch.getfloat('input', 'bluewidth', default=4. / arguments_freqrange[1])
            bluewidth = EEGsynth.rescale(bluewidth, slope=scale_blue, offset=offset_blue) * arguments_freqrange[1]
            blueleft_curr[plotnr].setData(x=[bluefreq - bluewidth, bluefreq - bluewidth], y=[specmin_curr[plotnr], specmax_curr[plotnr]])
            blueright_curr[plotnr].setData(x=[bluefreq + bluewidth, bluefreq + bluewidth], y=[specmin_curr[plotnr], specmax_curr[plotnr]])
            blueleft_hist[plotnr].setData(x=[bluefreq - bluewidth, bluefreq - bluewidth], y=[specmin_hist[plotnr], specmax_hist[plotnr]])
            blueright_hist[plotnr].setData(x=[bluefreq + bluewidth, bluefreq + bluewidth], y=[specmin_hist[plotnr], specmax_hist[plotnr]])
            # update labels at the vertical lines
            text_blueleft_curr.setText('%0.1f' % (bluefreq - bluewidth))
            text_blueleft_curr.setPos(bluefreq - bluewidth, specmax_curr[0])
            text_blueright_curr.setText('%0.1f' % (bluefreq + bluewidth))
            text_blueright_curr.setPos(bluefreq + bluewidth, specmax_curr[0])
            text_blueleft_hist.setText('%0.1f' % (bluefreq - bluewidth))
            text_blueleft_hist.setPos(bluefreq - bluewidth, specmax_hist[0])
            text_blueright_hist.setText('%0.1f' % (bluefreq + bluewidth))
            text_blueright_hist.setPos(bluefreq + bluewidth, specmax_hist[0])
            # write the positions of the lines to Redis
            key = "%s.%s.%s" % (prefix, 'blueband', 'low')
            patch.setvalue(key, bluefreq - bluewidth)
            key = "%s.%s.%s" % (prefix, 'blueband', 'high')
            patch.setvalue(key, bluefreq + bluewidth)