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])
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)