예제 #1
0
    def prepare_graphics(self, container):
        canvas = Canvas()
        container.set_widget(canvas)

        self.text0 = Text('')
        self.text0.pos = -0.15, 0
        canvas.add_item(self.text0)
예제 #2
0
    def prepare_graphics(self, container):
        self.plt = pg.PlotWidget()
        self.plots = []
        self.canvas = Canvas()
        self.cursors = []
        self.targets = []
        for i in np.arange(config['numbands']):
            # Plotting
            self.plots.append(
                self.plt.plot([], [],
                              pen=pg.intColor(i, hues=config['numbands'])))

            # Feedback
            self.cursors.append(
                Circle(0.1, color=pg.intColor(i, hues=config['numbands'])))
            self.cursors[i].pos = self.cursorx[i], 0  # evenly space
            self.canvas.add_item(self.cursors[i])

            # Training
            self.targets.append(Circle(0.1, color='#32b124'))
            self.targets[i].pos = self.cursorx[i], .5  # evenly space
            self.canvas.add_item(self.targets[i])

        self.plt.setRange(yRange=(0, .2), xRange=(0, 200))

        # Qt
        layout = QtGui.QGridLayout()
        container.setLayout(layout)
        layout.addWidget(self.canvas, 0, 0)  # 1st column
        layout.addWidget(self.plt, 0, 1)  # 2nd column
예제 #3
0
 def prepare_graphics(self, container):
     """Define the GUI by using Items etc.
     """
     self.canvas = Canvas()
     self.text = Text(text='', color='red')
     self.canvas.add_item(self.text)
     container.set_widget(self.canvas)
예제 #4
0
 def prepare_graphics(self, container):
     self.canvas = Canvas()
     self.cursor = Circle(0.05, color='#aa1212')
     self.target = Circle(0.1, color='#32b124')
     self.canvas.add_item(self.target)
     self.canvas.add_item(self.cursor)
     self.canvas.add_item(Cross())
     container.set_widget(self.canvas)
예제 #5
0
class Exertion(Task):
    def __init__(self, pipeline):
        super().__init__()
        self.pipeline = pipeline

    def prepare_design(self, design):
        block = design.add_block()
        for trial in [True] * 2:
            block.add_trial()

    def prepare_storage(self, storage):
        self.writer = storage.create_task('Exertiontask_' +
                                          time.strftime("%Y%m%d-%H%M%S"))

    def prepare_graphics(self, container):
        self.countdown = Canvas()
        self.countdowntext = Text("Flex!")
        self.countdown.add_item(self.countdowntext)
        container.set_widget(self.countdown)

    def prepare_daq(self, daqstream):
        self.daqstream = daqstream
        self.daqstream.start()

        self.timer = Counter(10)
        self.timer.timeout.connect(self.finish_trial)

    def run_trial(self, trial):
        self.timer.reset()
        self.pipeline.clear()
        self.connect(self.daqstream.updated, self.update)

    def update(self, data):
        self.integratedEMG = self.pipeline.process(data)[1:]
        self.timer.increment()

    def finish_trial(self):
        self.trial.attrs['Exertion'] = self.integratedEMG
        self.writer.write(self.trial)
        self.disconnect(self.daqstream.updated, self.update)
        self.next_trial()

    def finish(self):
        self.daqstream.stop()
        self.finished.emit()

    def key_press(self, key):
        if key == util.key_escape:
            self.finish()
        if key == util.key_q:
            sys.exit()
        else:
            super().key_press(key)
예제 #6
0
파일: test_gui.py 프로젝트: wind666/axopy
def test_container_layout():
    layout = QtWidgets.QVBoxLayout()
    layout.addWidget(QtWidgets.QPushButton())
    layout.addWidget(Canvas())

    c = Container()
    c.set_layout(layout)
예제 #7
0
파일: experiment.py 프로젝트: wind666/axopy
    def run(self, *tasks):
        """Run the experimental tasks."""
        if self.subject is None:
            self.configure()

        self.screen.key_pressed.connect(self.key_press)

        # screen to show "Ready" between tasks
        self.confirm_screen = Canvas(draw_border=False)
        self.confirm_screen.add_item(Text("Ready (enter to start)"))

        self.storage.subject_id = self.subject
        self.tasks = tasks

        self.current_task = None
        self.task_iter = iter(self.tasks)
        self._task_finished()

        self.screen.run()
예제 #8
0
    def run(self, *tasks):
        """Run the experimental tasks."""
        if self.subject is None:
            self.configure()

        self.screen.key_pressed.connect(self.key_press)

        # screen to show "Ready" between tasks
        self.confirm_screen = Canvas(draw_border=False)
        self.confirm_screen.add_item(Text("Ready (enter to start)"))

        self.storage.subject_id = self.subject
        self.tasks = tasks

        self.current_task = None
        self.task_iter = iter(self.tasks)
        self._task_finished()

        self.screen.run()
예제 #9
0
    def prepare_graphics(self, container):
        self.text0 = Text('Master: 0')
        self.text0.pos = -0.2, 0.5

        self.text1 = Text('Daq 1: 0')
        self.text1.pos = -0.2, 0

        self.text2 = Text('Daq 2: 0')
        self.text2.pos = -0.2, -0.5

        canvas = Canvas()
        canvas.add_item(self.text0)
        canvas.add_item(self.text1)
        canvas.add_item(self.text2)
        container.set_widget(canvas)
예제 #10
0
    def prepare_graphics(self, container):
        canvas = Canvas()
        container.set_widget(canvas)

        # create a couple text items that tick with each daq update
        self.text1 = Text('0')
        self.text1.pos = -0.5, 0
        canvas.add_item(self.text1)

        self.text2 = Text('0')
        self.text2.pos = 0.5, 0
        canvas.add_item(self.text2)

        # counters keeping track of the updates
        self.counter1 = Counter(100, reset_on_timeout=False)
        self.counter2 = Counter(100, reset_on_timeout=False)

        # stop updating when the faster DAQ has updated 100 times
        self.counter1.timeout.connect(self.done)
예제 #11
0
class CursorFollowing(Task):
    # TODO split this into two tasks (a "training" task and a "practice" task).
    # This would involve storing the RLS weights and loading them for the
    # practice task. Probably a good idea to write a simple cursor interface
    # class to share common code between the two tasks.

    target_dist = 0.8

    def __init__(self, pipeline):
        super(CursorFollowing, self).__init__()
        self.pipeline = pipeline

    def prepare_design(self, design):
        d = self.target_dist
        target_positions = [(d, 0), (0, d), (-d, 0), (0, -d), (0, 0)]
        for training in [True, False]:
            block = design.add_block()
            for x, y in target_positions:
                block.add_trial(attrs={
                    'target_x': x,
                    'target_y': y,
                    'training': training
                })
            block.shuffle()

    def prepare_graphics(self, container):
        self.canvas = Canvas()
        self.cursor = Circle(0.05, color='#aa1212')
        self.target = Circle(0.1, color='#32b124')
        self.canvas.add_item(self.target)
        self.canvas.add_item(self.cursor)
        self.canvas.add_item(Cross())
        container.set_widget(self.canvas)

    def prepare_daq(self, daqstream):
        self.daqstream = daqstream
        self.daqstream.start()

        self.timer = Counter(50)
        self.timer.timeout.connect(self.finish_trial)

    def run_trial(self, trial):
        if not trial.attrs['training']:
            self.target.color = '#3224b1'
        self._reset()
        self.target.pos = trial.attrs['target_x'], trial.attrs['target_y']
        self.target.show()
        self.pipeline.clear()
        self.connect(self.daqstream.updated, self.update)

    def update(self, data):
        xhat = self.pipeline.process(data)
        self.cursor.pos = xhat

        target_pos = numpy.array(
            [self.trial.attrs['target_x'], self.trial.attrs['target_y']])
        if self.trial.attrs['training']:
            self.pipeline.named_blocks['RLSMapping'].update(target_pos)

        if self.cursor.collides_with(self.target):
            self.finish_trial()

        self.timer.increment()

    def finish_trial(self):
        self.disconnect(self.daqstream.updated, self.update)
        self._reset()
        self.next_trial()

    def _reset(self):
        self.cursor.pos = 0, 0
        self.timer.reset()
        self.target.hide()

    def finish(self):
        self.daqstream.stop()

    def key_press(self, key):
        if key == util.key_escape:
            self.finish()
        else:
            super().key_press(key)
예제 #12
0
파일: test_gui.py 프로젝트: wind666/axopy
def test_canvas():
    c = Canvas()
    c.add_item(Circle(0.1))
    c.add_item(Circle(0.1).qitem)
예제 #13
0
class PartialPowers(Task):
    def __init__(self, pipeline):
        super().__init__()
        self.pipeline = pipeline

    def prepare_design(self, design):
        # yikes... evenly space along the horizontal
        self.cursorx = [(i + 1.) * 2 / (config['numbands'] + 1.) - 1.
                        for i in np.arange(config['numbands'])]
        # returns array of all possible combinations
        self.active_targets = np.unpackbits(
            np.arange(np.power(2, config['numbands']), dtype=np.uint8)[:,
                                                                       None],
            axis=1)[:, -config['numbands']:] / 2 + .25

        for training in [True] * 10:
            block = design.add_block()
            for active in self.active_targets:
                block.add_trial(attrs={
                    'active_targets': active,
                    'training': training
                })
            block.shuffle()

    def prepare_storage(self, storage):
        self.writer = storage.create_task('training task_' +
                                          time.strftime("%Y%m%d-%H%M%S"))

    def prepare_graphics(self, container):
        self.plt = pg.PlotWidget()
        self.plots = []
        self.canvas = Canvas()
        self.cursors = []
        self.targets = []
        for i in np.arange(config['numbands']):
            # Plotting
            self.plots.append(
                self.plt.plot([], [],
                              pen=pg.intColor(i, hues=config['numbands'])))

            # Feedback
            self.cursors.append(
                Circle(0.1, color=pg.intColor(i, hues=config['numbands'])))
            self.cursors[i].pos = self.cursorx[i], 0  # evenly space
            self.canvas.add_item(self.cursors[i])

            # Training
            self.targets.append(Circle(0.1, color='#32b124'))
            self.targets[i].pos = self.cursorx[i], .5  # evenly space
            self.canvas.add_item(self.targets[i])

        self.plt.setRange(yRange=(0, .2), xRange=(0, 200))

        # Qt
        layout = QtGui.QGridLayout()
        container.setLayout(layout)
        layout.addWidget(self.canvas, 0, 0)  # 1st column
        layout.addWidget(self.plt, 0, 1)  # 2nd column

    def prepare_daq(self, daqstream):
        self.daqstream = daqstream
        self.daqstream.start()

        self.timer = Counter(100)
        self.timer.timeout.connect(self.finish_trial)

    def run_trial(self, trial):
        # change the color of the target cursor depending if training
        if not trial.attrs['training']:
            for i in np.arange(config['numbands']):
                self.targets[i].color = '#3224b1'
        self._reset()
        # set the target positions
        for i in np.arange(config['numbands']):
            self.targets[i].pos = self.cursorx[i], trial.attrs[
                'active_targets'][i]
            self.targets[i].show()
        self.pipeline.clear()
        self.connect(self.daqstream.updated, self.update)

    def update(self, data):
        self.weights = np.multiply([0.33271298928451853, 0.62291817090414547],
                                   .2)
        self.differencefactor = 0.1
        self.integratedEMG = self.pipeline.process(data)
        self.windoweddata = self.integratedEMG.pop(0)
        for i in np.arange(config['numbands']):
            # self.plots[i].setData(self.freq, self.powers[:, i])
            self.cursors[i].y = self.integratedEMG[i] / self.weights[
                i] - self.differencefactor * np.sum(
                    np.delete(self.integratedEMG, i) /
                    np.delete(self.weights, i))

        target_pos = np.array(self.trial.attrs['active_targets']).flatten()
        if all(
                cursor.collides_with(self.targets[i])
                for i, cursor in enumerate(self.cursors)):
            self.finish_trial()

        self.timer.increment()

    def finish_trial(self):
        self.trial.attrs['final_cursor_pos'] = [
            self.cursors[i].pos[1] for i in np.arange(config['numbands'])
        ]
        self.trial.attrs['time'] = self.timer.count
        self.trial.attrs['timeout'] = self.trial.attrs['time'] < 1
        self.trial.add_array(
            'windowedEMG',
            data=self.windoweddata)  # TODO: complain to kenny about this
        self.writer.write(self.trial)
        self.disconnect(self.daqstream.updated, self.update)
        self._reset()
        self.next_trial()

    def _reset(self):
        for i in np.arange(config['numbands']):
            self.cursors[i].pos = self.cursorx[i], 0  # evenly space
            self.targets[i].hide()
        self.timer.reset()

    def finish(self):
        self.daqstream.stop()
        self.finished.emit()

    def key_press(self, key):
        if key == util.key_escape:
            self.finish()
        if key == util.key_q:
            sys.exit()
        else:
            super().key_press(key)
예제 #14
0
파일: emg.py 프로젝트: krmdmn/axopy
    def prepare_graphics(self, container):
        self.canvas = Canvas()
        container.set_widget(self.canvas)

        self.init_widgets()
예제 #15
0
class ValuePrint(Task):
    def __init__(self, pipeline):
        """The only thing we need to include in the constructor is the
        pipeline.
        """
        super(ValuePrint, self).__init__()
        self.pipeline = pipeline

    def prepare_design(self, design):
        """Prepare experimental design. Here is where we define the number of
        blocks and trials within each block.
        """
        block = design.add_block()
        block.add_trial(attrs={})

    def prepare_graphics(self, container):
        """Define the GUI by using Items etc.
        """
        self.canvas = Canvas()
        self.text = Text(text='', color='red')
        self.canvas.add_item(self.text)
        container.set_widget(self.canvas)

    def prepare_daq(self, daqstream):
        """Initialize input stream and define how many updates (i.e., cycles)
        take place within each trial (optional).
        """
        self.daqstream = daqstream
        self.daqstream.start()
        # The following two lines define how many cycles will take place within
        # each trial. The length of the trial is n_cycles * (read_size) / rate.
        # When the counter reaches the maximum count value it will send a
        # a signal to start the new trial.
        self.timer = Counter(50)
        self.timer.timeout.connect(self.finish_trial)

    def run_trial(self, trial):
        self.pipeline.clear()
        self.connect(self.daqstream.updated, self.update)

    def update(self, data):
        """Define what happens at each update operation (e.g. )
        """
        data_proc = self.pipeline.process(data)
        self.text.qitem.setText("{:4.4f}".format(data_proc))

        # The following lines tells the timer that an update has happened
        # so as to keep track of the cycles and end the program after n_cycles
        # have happened.
        self.timer.increment()

    def finish_trial(self):
        self.disconnect(self.daqstream.updated, self.update)
        self.next_trial()

    def finish(self):
        self.daqstream.stop()
        self.finished.emit()

    def key_press(self, key):
        if key == util.key_escape:
            self.finish()
        else:
            super().key_press(key)
예제 #16
0
파일: experiment.py 프로젝트: wind666/axopy
class Experiment(TransmitterBase):
    """Experiment workflow manager.

    Presents the researcher with a prompt for entering session details and then
    presents the appropriate tasks.

    Parameters
    ----------
    daq : object, optional
        A data acquisition device that follows the AxoPy DAQ protocol. See
        :mod:`axopy.daq`. For mutliple devices, a dictionary, list or tuple
        is expected.
    data : str, optional
        Path to the data. The directory is created for you if it doesn't exist.
    subject : str, optional
        The subject ID to use. If not specified, a configuration screen is
        shown before running the tasks so you can enter it there. This is
        mostly for experiment writing (to avoid the extra configuration step).
    allow_overwrite : bool, optional
        If ``True``, overwrite protection in :class:`Storage` is disabled. This
        is mostly for experiment writing purposes.
    """

    key_pressed = Transmitter(str)

    def __init__(self,
                 daq=None,
                 data='data',
                 subject=None,
                 allow_overwrite=False):
        super(Experiment, self).__init__()
        self.daq = daq

        self.storage = Storage(data, allow_overwrite=allow_overwrite)

        self._receive_keys = False

        self.subject = subject

        # main screen
        self.screen = _MainWindow()

        # Prepare daqstream(s)
        self._prepare_daqstream()

    def configure(self, **options):
        """Configure the experiment with custom options.

        This method allows you to specify a number of options that you want to
        configure with a graphical interface prior to running the tasks. Use
        keyword arguments to specify which options you want to configure. The
        options selected/specified in the graphical interface are then returned
        by this method so that you can alter setup before running the
        experiment.

        Each keyword argument should list the data type to configure, such as
        ``float``, ``str``, or ``int``. You can also provide a list or tuple of
        available choices for that option.

        You *do not* need to add an option for the subject name/ID -- that is
        added automatically if the subject ID was not specified when creating
        the experiment.
        """
        options['subject'] = str
        config = _SessionConfig(options).run()
        self.subject = config['subject']
        return config

    def run(self, *tasks):
        """Run the experimental tasks."""
        if self.subject is None:
            self.configure()

        self.screen.key_pressed.connect(self.key_press)

        # screen to show "Ready" between tasks
        self.confirm_screen = Canvas(draw_border=False)
        self.confirm_screen.add_item(Text("Ready (enter to start)"))

        self.storage.subject_id = self.subject
        self.tasks = tasks

        self.current_task = None
        self.task_iter = iter(self.tasks)
        self._task_finished()

        self.screen.run()

    @property
    def status(self):
        return "subject: {} | task: {}".format(
            self.subject, self.current_task.__class__.__name__)

    def _run_task(self):
        self._receive_keys = False

        # wait for task to finish
        self.current_task.finished.connect(self._task_finished)
        # forward key presses to the task
        self.key_pressed.connect(self.current_task.key_press)

        self.screen.set_status(self.status)

        # add a task view
        con = self.screen.new_container()

        self.current_task.prepare_graphics(con)
        self.current_task.prepare_daq(self.daqstream)
        self.current_task.prepare_storage(self.storage)
        self.current_task.run()

    def _task_finished(self):
        if self.current_task is not None:
            self.current_task.disconnect_all()
            self.current_task.finished.disconnect(self._task_finished)
            self.key_pressed.disconnect(self.current_task.key_press)

        try:
            self.current_task = next(self.task_iter)
        except StopIteration:
            self.screen.quit()

        self.screen.set_container(self.confirm_screen)
        self._receive_keys = True

    def key_press(self, key):
        if self._receive_keys:
            if key == util.key_escape:
                self.screen.quit()
            elif key == util.key_return:
                self._run_task()
        else:
            self.key_pressed.emit(key)

    def _prepare_daqstream(self):
        if isinstance(self.daq, (list, tuple)):
            self.daqstream = []
            for daq_ in self.daq:
                self.daqstream.append(DaqStream(daq_))
        elif isinstance(self.daq, dict):
            self.daqstream = dict()
            for daq_name, daq_ in self.daq.items():
                self.daqstream[daq_name] = DaqStream(daq_)
        else:
            self.daqstream = DaqStream(self.daq)
예제 #17
0
 def prepare_graphics(self, container):
     self.countdown = Canvas()
     self.countdowntext = Text("Flex!")
     self.countdown.add_item(self.countdowntext)
     container.set_widget(self.countdown)
예제 #18
0
class Experiment(TransmitterBase):
    """Experiment workflow manager.

    Presents the researcher with a prompt for entering session details and then
    presents the appropriate tasks.

    Parameters
    ----------
    daq : object, optional
        A data acquisition device that follows the AxoPy DAQ protocol. See
        :mod:`axopy.daq`.
    data : str, optional
        Path to the data. The directory is created for you if it doesn't exist.
    subject : str, optional
        The subject ID to use. If not specified, a configuration screen is
        shown before running the tasks so you can enter it there. This is
        mostly for experiment writing (to avoid the extra configuration step).
    allow_overwrite : bool, optional
        If ``True``, overwrite protection in :class:`Storage` is disabled. This
        is mostly for experiment writing purposes.
    """

    key_pressed = Transmitter(str)

    def __init__(self, daq=None, data='data', subject=None,
                 allow_overwrite=False):
        super(Experiment, self).__init__()
        self.daq = daq
        self.daqstream = DaqStream(daq)
        self.storage = Storage(data, allow_overwrite=allow_overwrite)

        self._receive_keys = False

        self.subject = subject

        # main screen
        self.screen = _MainWindow()

    def configure(self, **options):
        """Configure the experiment with custom options.

        This method allows you to specify a number of options that you want to
        configure with a graphical interface prior to running the tasks. Use
        keyword arguments to specify which options you want to configure. The
        options selected/specified in the graphical interface are then returned
        by this method so that you can alter setup before running the
        experiment.

        Each keyword argument should list the data type to configure, such as
        ``float``, ``str``, or ``int``. You can also provide a list or tuple of
        available choices for that option.

        You *do not* need to add an option for the subject name/ID -- that is
        added automatically if the subject ID was not specified when creating
        the experiment.
        """
        options['subject'] = str
        config = _SessionConfig(options).run()
        self.subject = config['subject']
        return config

    def run(self, *tasks):
        """Run the experimental tasks."""
        if self.subject is None:
            self.configure()

        self.screen.key_pressed.connect(self.key_press)

        # screen to show "Ready" between tasks
        self.confirm_screen = Canvas(draw_border=False)
        self.confirm_screen.add_item(Text("Ready (enter to start)"))

        self.storage.subject_id = self.subject
        self.tasks = tasks

        self.current_task = None
        self.task_iter = iter(self.tasks)
        self._task_finished()

        self.screen.run()

    @property
    def status(self):
        return "subject: {} | task: {}".format(
            self.subject, self.current_task.__class__.__name__)

    def _run_task(self):
        self._receive_keys = False

        # wait for task to finish
        self.current_task.finished.connect(self._task_finished)
        # forward key presses to the task
        self.key_pressed.connect(self.current_task.key_press)

        self.screen.set_status(self.status)

        # add a task view
        con = self.screen.new_container()

        self.current_task.prepare_graphics(con)
        self.current_task.prepare_daq(self.daqstream)
        self.current_task.prepare_storage(self.storage)
        self.current_task.run()

    def _task_finished(self):
        if self.current_task is not None:
            self.current_task.disconnect_all()
            self.current_task.finished.disconnect(self._task_finished)
            self.key_pressed.disconnect(self.current_task.key_press)

        try:
            self.current_task = next(self.task_iter)
        except StopIteration:
            self.screen.quit()

        self.screen.set_container(self.confirm_screen)
        self._receive_keys = True

    def key_press(self, key):
        if self._receive_keys:
            if key == util.key_escape:
                self.screen.quit()
            elif key == util.key_return:
                self._run_task()
        else:
            self.key_pressed.emit(key)