def make_scope_pipeline(self): windower = Windower(int(self.rate * self.win_size_disp)) if self.filter: filter = self.make_filter(win_size=self.win_size_disp) if self.filter: self.pipeline['scope'] = Pipeline([windower, filter]) else: self.pipeline['scope'] = Pipeline([windower])
def make_mav_norm_pipeline(self): windower = Windower(int(self.rate * self.win_size_mav)) if self.filter: filter = self.make_filter(win_size=self.win_size_mav) fe = FeatureExtractor([('MAV', MeanAbsoluteValue())]) mmsc = MinMaxScaler(min_=self.c_min, max_=self.c_max) # Calibrated MAV is non-negative, but we allow values larger than 1 nonneg = Callable(lambda x: np.clip(x, 0.0, None)) if self.filter: self.pipeline['mav_norm'] = Pipeline( [windower, filter, fe, mmsc, nonneg]) else: self.pipeline['mav_norm'] = Pipeline([windower, fe, mmsc, nonneg])
def make_mav_win_pipeline(self): windower_pre = Windower(int(self.rate * self.win_size_mav)) if self.filter: filter = self.make_filter(win_size=self.win_size_mav) fe = FeatureExtractor([('MAV', MeanAbsoluteValue())]) e2d = Ensure2D(orientation='col') windower_post = Windower( int((1 / self.read_length) * self.win_size_calib)) if self.filter: self.pipeline['mav_win'] = Pipeline( [windower_pre, filter, fe, e2d, windower_post]) else: self.pipeline['mav_win'] = Pipeline( [windower_pre, fe, e2d, windower_post])
def emgsim(): # sampling rate of the simulated EMG data fs = 2000 # update rate of the generated data update_rate = 20 # gain to use in noise generation gain = 0.25 # number of seconds of data the oscilloscope shows osc_view_time = 5 samp_per_input = int(fs / update_rate) pipeline = Pipeline([ # get keyboard inputs of past second Windower(update_rate), # take mean over last second and apply a gain Callable(lambda x: np.mean(x, axis=1, keepdims=True)), # generate noise with amplitude of previous output Callable(lambda x, k: gain * x * np.random.randn(x.shape[0], k), func_args=(samp_per_input, )), # window for pretty display in oscilloscope Windower(osc_view_time * update_rate * samp_per_input), ]) dev = Keyboard(rate=update_rate, keys=list('wasd')) run(dev, pipeline)
def myoimu(): import myo from pydaqs.myo import MyoIMU myo.init(sdk_path=r'C:\Users\nak142\Coding\myo-python\myo-sdk-win-0.9.0') dev = MyoIMU(samples_per_read=5) pipeline = Pipeline([Windower(500)]) channel_names = list('wxyz') run(dev, pipeline, channel_names=channel_names)
def mouse(): dev = Mouse(rate=20) pipeline = Pipeline([ # just for scaling the input since it's in pixels Callable(lambda x: x / 100), # window to show in the oscilloscope Windower(40) ]) run(dev, pipeline)
def nidaq(): from pydaqs.nidaq import Nidaq n_channels = 4 dev = Nidaq(channels=range(n_channels), samples_per_read=200, rate=2000, zero_based=False) pipeline = Pipeline([Windower(20000)]) channel_names = ['EMG ' + str(i) for i in range(1, n_channels + 1)] run(dev, pipeline, channel_names=channel_names)
def myoemg(): import myo from pydaqs.myo import MyoEMG # Set the dir where myo-sdk is stored myo.init(sdk_path=r'C:\Users\nak142\Coding\myo-python\myo-sdk-win-0.9.0') n_channels = 8 dev = MyoEMG(channels=range(n_channels), samples_per_read=20) pipeline = Pipeline([Windower(2000)]) channel_names = ['EMG ' + str(i) for i in range(1, n_channels + 1)] run(dev, pipeline, channel_names=channel_names, yrange=(-150, 150))
def make_pipeline(self, gain): b, a = butter(4, (10 / 2000. / 2., 900 / 2000. / 2.), 'bandpass') pipeline = Pipeline([ Windower(250), Filter(b, a=a, overlap=150), # overlap = winsize - read_rate Callable(lambda x: x[:, 0].reshape(-1, 1)), # Downsampling Callable(lambda x: gain * x) ]) return pipeline
def blackrock(): from pydaqs.blackrock import Blackrock from axopy.gui.main import get_qtapp n_channels = 1 # Needed to avoid having Cerelink create the QCoreApplication _ = get_qtapp() dev = Blackrock(channels=range(1, n_channels + 1), samples_per_read=20) pipeline = Pipeline([Windower(5000)]) channel_names = ['EMG ' + str(i) for i in range(1, n_channels + 1)] run(dev, pipeline, channel_names=channel_names, yrange=(-1000, 1000))
def cyberglove(): from cyberglove import CyberGlove n_df = 18 s_port = 'COM6' dev = CyberGlove(n_df=n_df, s_port=s_port, samples_per_read=1, cal_path=None) pipeline = Pipeline([Windower(1000)]) channel_names = ['DOF ' + str(i) for i in range(1, n_df + 1)] run(dev, pipeline, channel_names=channel_names, yrange=(0, 200))
def arduino(): from pydaqs.arduino import ArduinoDAQ pins = [0, 1, 2] dev = ArduinoDAQ(rate=1000, port='COM5', pins=pins, samples_per_read=10, zero_based=True) pipeline = Pipeline([Windower(10000)]) channel_names = ['A ' + str(i) for i in pins] run(dev, pipeline, channel_names=channel_names, yrange=(0, 1))
def trignoemg(): from pytrigno import TrignoEMG n_channels = 8 dev = TrignoEMG(channels=range(1, n_channels + 1), samples_per_read=200, zero_based=False, units='normalized', data_port=50043) pipeline = Pipeline([Windower(20000)]) channel_names = ['EMG ' + str(i) for i in range(1, n_channels + 1)] run(dev, pipeline, channel_names=channel_names)
def keystick(): dev = Keyboard(rate=20, keys=list('wasd')) pipeline = Pipeline([ # window to average over Windower(10), # mean along rows Callable(lambda x: np.mean(x, axis=1, keepdims=True)), # window to show in the oscilloscope Windower(60) ]) run(dev, pipeline)
def trignoacc(): from pytrigno import TrignoACC n_channels = 8 dev = TrignoACC(channels=range(1, n_channels + 1), samples_per_read=12, data_port=50042, zero_based=False) pipeline = Pipeline([Windower(1200)]) channel_names = [ 'Acc ' + str(i) + '_' + axis for i in range(1, n_channels + 1) for axis in ['x', 'y', 'z'] ] run(dev, pipeline, channel_names=channel_names)
def trignoimu(): from pytrigno import TrignoIMU n_channels = 2 dev = TrignoIMU(channels=range(1, n_channels + 1), samples_per_read=12, imu_mode='raw', data_port=50044, zero_based=False) pipeline = Pipeline([Windower(1200)]) channel_names = [ mod + '_' + str(i) + '_' + axis for i in range(1, n_channels + 1) for mod in ['Acc', 'Gyro', 'Mag'] for axis in ['x', 'y', 'z'] ] run(dev, pipeline, channel_names=channel_names)
def quattroimu(): from pytrigno import QuattroIMU n_sensors = 2 dev = QuattroIMU(sensors=range(1, n_sensors + 1), samples_per_read=12, data_port=50044, mode=313, zero_based=False) pipeline = Pipeline([Windower(1200)]) channel_names = [ str(i) + '_' + axis for i in range(1, n_sensors + 1) for axis in ['a', 'b', 'c', 'd'] ] run(dev, pipeline, channel_names=channel_names)
def polar(): num_channels = 5 dev = RandomWalkGenerator(rate=60, num_channels=num_channels, amplitude=0.03, read_size=1) # Polar plot can only show non-negative values pipeline = Pipeline([Callable(lambda x: np.abs(x))]) Experiment(daq=dev, subject='test').run( PolarPlotter(pipeline, color=[0, 128, 255], fill=True, n_circles=10, max_value=5.))
def make_pipeline(self, rate, readsize, winsize, lowpass, highpass): b, a = butter(4, (lowpass / rate / 2., highpass / rate / 2.), 'bandpass') pipeline = Pipeline([ Windower(winsize), # overlap = winsize - read_rate Filter(b, a=a, overlap=winsize - readsize), Callable(mean_absolute_value, func_kwargs={ 'axis': 1, 'keepdims': True }) ]) return pipeline
def quattroemg(): from pytrigno import QuattroEMG n_sensors = 2 dev = QuattroEMG(sensors=range(1, n_sensors + 1), samples_per_read=200, zero_based=False, mode=313, units='normalized', data_port=50043) pipeline = Pipeline([Windower(20000)]) channel_names = [ str(i) + channel for i in range(1, n_sensors + 1) for channel in ['A', 'B', 'C', 'D'] ] run(dev, pipeline, channel_names=channel_names)
def bar(): num_channels = 10 channel_names = ['Ch ' + str(i) for i in range(1, num_channels + 1)] dev = NoiseGenerator(rate=100, num_channels=num_channels, amplitude=5.0, read_size=10) pipeline = Pipeline( [Windower(100), Callable(lambda x: np.mean(x, axis=1, keepdims=True))]) Experiment(daq=dev, subject='test').run( BarPlotter(pipeline=pipeline, channel_names=channel_names, group_colors=[[255, 204, 204]], yrange=(-0.5, 0.5)))
def udpsocket(): from threading import Thread from pydaqs.socket import UDPSocketReader ip = "127.0.0.1" port = 5005 array_len = 8 precision = 'single' dev = UDPSocketReader(ip=ip, port=port, array_len=array_len, samples_per_read=1, precision=precision, timeout=None) pipeline = Pipeline([Windower(25)]) run(dev, pipeline, yrange=(-3, 3))
def tcpsocket(): from threading import Thread from pydaqs.socket import TCPSocketReader ip = "127.0.0.1" port = 5005 array_len = 4 precision = 'double' dev = TCPSocketReader(ip=ip, port=port, array_len=array_len, samples_per_read=1, precision=precision, timeout=3) pipeline = Pipeline([Windower(25)]) _ = Thread(target=_tcp_socket_streamer, args=(ip, port, array_len, precision), daemon=True).start() run(dev, pipeline, yrange=(-3, 3))
def make_display_pipeline(self): # Windower to display something meaningful on Oscilloscope self.display_pipeline = Pipeline([Windower(30)])
class MyTask(Task): def __init__(self): super(MyTask, self).__init__() self.make_display_pipeline() def prepare_design(self, design): n_trials = 2 # Two conditions with different set of parameters for gain in [1, 3]: block = design.add_block() for trial in range(n_trials): block.add_trial(attrs={'gain': gain}) block.shuffle() def prepare_graphics(self, container): self.scope = SignalWidget() container.set_widget(self.scope) def prepare_storage(self, storage): # TODO self.writer = storage.create_task('my_task') def prepare_daq(self, daqstream): self.daqstream = daqstream self.daqstream.start() # If we want every trial to have specified length we need to use # something like this. This is reset at the start of every new trial. self.timer = Counter(50) # number of daq read cycles self.timer.timeout.connect(self.finish_trial) def make_pipeline(self, gain): b, a = butter(4, (10 / 2000. / 2., 900 / 2000. / 2.), 'bandpass') pipeline = Pipeline([ Windower(250), Filter(b, a=a, overlap=150), # overlap = winsize - read_rate Callable(lambda x: x[:, 0].reshape(-1, 1)), # Downsampling Callable(lambda x: gain * x) ]) return pipeline def make_display_pipeline(self): # Windower to display something meaningful on Oscilloscope self.display_pipeline = Pipeline([Windower(30)]) def run_trial(self, trial): # Display trial details in console print("Block {}, trial {}, gain {}.".format(trial.attrs['block'], trial.attrs['trial'], trial.attrs['gain'])) self.reset() trial.add_array('data_raw', stack_axis=1) trial.add_array('data_proc', stack_axis=1) # The processing pipeline is created in each trial because it depends # upon the gain defined by the trial self.pipeline = self.make_pipeline(trial.attrs['gain']) # This is where the magic happens. Every time the a read operation is # performed a signal is emitted to process the data and do something self.connect(self.daqstream.updated, self.update) def reset(self): self.timer.reset() # Clear data from window used for Oscilloscope. The processing pipeline # does not need to be reset because it is overwritten in every trial self.display_pipeline.clear() def update(self, data): # This is the main loop within the trial data_proc = self.pipeline.process(data) data_display = self.display_pipeline.process(data_proc) self.scope.plot(data_display) # Update Arrays self.trial.arrays['data_raw'].stack(data) self.trial.arrays['data_proc'].stack(data_proc) self.timer.increment() def finish_trial(self): self.writer.write(self.trial) self.disconnect(self.daqstream.updated, self.update) # Wait 1 second before the new trial self.wait_timer = Timer(1) self.wait_timer.timeout.connect(self.next_trial) self.wait_timer.start() def key_press(self, key): super(MyTask, self).key_press(key) if key == util.key_escape: self.finish() def finish(self): self.daqstream.stop() self.finished.emit()
def keyboard(): keys = list('wasd') dev = Keyboard(keys=keys) # need a windower to show something interesting in the oscilloscope pipeline = Pipeline([Windower(10)]) run(dev, pipeline, channel_names=keys)
def keyboard(): dev = Keyboard() # need a windower to show something interesting in the oscilloscope pipeline = Pipeline([Windower(10)]) run(dev, pipeline)