def run(self, *args, **kwargs): """""" delay = w.get_value('delay') pulse = w.get_value('pulse') if hasattr(self, 'timer_cue'): timer.clear_interval(self.timer_cue) self.timer_cue = timer.set_interval(lambda: self.trial(pulse), delay)
def __init__(self, *args, **kwargs): """""" super().__init__(*args, **kwargs) self.add_stylesheet('styles.css') self.show_cross() self.dashboard <= w.label('4-Class motor imagery', 'headline4') self.dashboard <= w.checkbox( label='Cues', options=[[cue, True] for cue in UNICODE_CUES], on_change=None, id='cues', ) self.dashboard <= w.slider( label='Trials per class:', min=1, max=100, value=10, step=1, discrete=True, marks=True, id='repetitions', ) self.dashboard <= w.slider( label='Stimulus duration', min=2000, max=6000, value=4000, step=100, unit='ms', id='duration', ) self.dashboard <= w.range_slider( label='Stimulus onset asynchronously', min=1000, max=3000, value_lower=2000, value_upper=3000, step=100, unit='ms', id='soa', ) self.dashboard <= w.switch( label='Record EEG', checked=False, id='record', ) self.dashboard <= w.switch( label='External marker synchronizer', checked=False, on_change=self.synchronizer, id='record', ) self.dashboard <= w.button('Start run', on_click=self.start) self.dashboard <= w.button('Stop run', on_click=self.stop)
def build_trials(self) -> None: """Define the `trials` and `pipeline trials`. The `trials` consist (in this case) in a list of cues. The `pipeline trials` is a set of couples `(callable, duration)` that define a single trial, this list of functions are executed asynchronously and repeated for each trial. """ self.trials = w.get_value('cues') * w.get_value('repetitions') random.shuffle(self.trials) self.pipeline_trial = [ (self.soa, 'soa'), # `soa` is a range reference (self.trial, 'duration'), # `duration` is a slider reference ]
def build_trials(self) -> None: """Define the `trials` and `pipeline trials`. The `trials` consist (in this case) in a list of cues. The `pipeline trials` is a set of couples `(callable, duration)` that define a single trial, this list of functions are executed asynchronously and repeated for each trial. """ self.propagate_seed() inter_stimulus = w.get_value('inter_stimulus') duration = w.get_value('duration') chars, ncols = CHARACTERS nrows = len(chars) // ncols self.trials = [] trials = w.get_value('trials') if trials == -1: trials = 99 for _ in range(trials): stimuli_array = [] for i in range(ncols): stimuli_array.append(f'.col-{i}') for i in range(nrows): stimuli_array.append(f'.row-{i}') random.shuffle(stimuli_array) self.trials.append({ 'target': random.choice(CHARACTERS_SRLZ), 'array': stimuli_array }) random.shuffle(self.trials) if not w.get_value('speller'): self.pipeline_trial = [(lambda **kwargs: None, 500), (self.target_notice, w.get_value('notice')), (self.inter_stimulus, 3000)] else: self.pipeline_trial = [] [ self.pipeline_trial.extend([(self.activate, 300), (self.inter_stimulus, 300)]) for _ in range(nrows + ncols) ]
def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.add_stylesheet('styles.css') self.show_cross() self.show_synchronizer() self.dashboard <= w.button('Button', on_click=self.on_button)
def start(self) -> None: """Start the run. A run consist in a consecutive pipeline trials execution. """ if w.get_value('record'): self.start_record() self.build_trials() timer.set_timeout( lambda: self.run_pipeline(self.pipeline_trial, self.trials), 2000)
def __init__(self, *args, **kwargs): """""" super().__init__(*args, **kwargs) self.listen_feedbacks(self.on_feedback) self.add_stylesheet('styles.css') self.show_cross() self.show_synchronizer() self.dashboard <= w.label( 'Latency measurement<br><br>', typo='headline4') self.dashboard <= w.slider( label='Delay', min=1000, max=10000, step=100, value=1000, on_change=self.run, unit='ms', id='delay' ) self.dashboard <= w.slider( label='Pulse duration', min=100, max=5000, step=100, value=500, on_change=self.run, unit='ms', id='pulse', ) self.dashboard <= w.button(label='Start run', on_click=self.start) self.dashboard <= w.button(label='Stop run', on_click=self.stop) self.start()
def blink(self): """""" if self.frame == 'secondary': item = random.choice( self.secondary_area.select(f'.cue.secondary.show')) elif self.frame == 'primary': item = random.choice(self.primary_area.select(f'.cue.primary')) if item == self.item: self.blink() return self.item = item if self.stimuli: self.blink_element(item) timer.set_timeout(self.blink, w.get_value('stimuli_interval'))
def stop_run(self) -> None: """Stop pipeline execution.""" self.soa() if w.get_value('record'): timer.set_timeout(self.stop_record, 2000)
def __init__(self, *args, **kwargs): """""" super().__init__(*args, **kwargs) self.add_stylesheet('styles.css') self.stimuli_area.style = {'background-color': 'black'} self.build_speller() self.build_grid() self.listen_feedbacks(self.on_feedback) self.dashboard <= w.label('P300 Speller', 'headline4') self.dashboard <= w.switch( label='Activate feedback speller', checked=False, on_change=self.show_speller, id='speller', ) self.dashboard <= w.slider(label='Trials:', min=-1, max=15, value=5, step=1, discrete=True, marks=True, id='trials') self.dashboard <= w.slider(label='Target notice:', min=500, max=5000, value=2000, step=100, unit='ms', id='notice') self.dashboard <= w.slider(label='Flash duration:', min=100, max=500, value=125, step=5, unit='ms', id='duration') self.dashboard <= w.slider(label='Inter stimulus interval:', min=10, max=500, value=62.5, step=5, unit='ms', id='inter_stimulus') self.dashboard <= w.switch( label='Record EEG', checked=False, id='record', ) self.dashboard <= w.switch( label='External marker synchronizer', checked=False, on_change=self.synchronizer, id='record', ) self.dashboard <= w.button('Start run', on_click=self.start) self.dashboard <= w.button('Stop run', on_click=self.stop)
def build_interface(self): """""" self.primary_area = html.DIV(Class='area primary-area') self.secondary_area = html.DIV(Class='secondary-area') for element in self.interface: key = element['id'] button = html.BUTTON(element['label'], Class='cue show primary') button.bind('click', self.show_secondary(key)) self.primary_area <= button if element['type'] == 'categorical': categorical_area = html.DIV(Class='categorical-area') for option in element['options']: categorical_area <= html.BUTTON( option, Class=f'cue show secondary primary-{key}') self.secondary_area <= categorical_area elif element['type'] == 'slider': increase_area = html.DIV(Class='slider-area') value_area = html.DIV(Class='slider-area') decrease_area = html.DIV(Class='slider-area') for increase in element['increase_modifiers']: increase_area <= html.BUTTON( increase, Class=f'cue show slider secondary primary-{key}') value_area <= html.BUTTON( element['value'], Class=f'secondary gui-value show primary-{key}') for decrease in element['decrease_modifiers']: decrease_area <= html.BUTTON( decrease, Class=f'cue show slider secondary primary-{key}') self.secondary_area <= increase_area + value_area + decrease_area elif element['type'] == 'boolean': boolean_area = html.DIV(Class='boolean-area') for label, name, value in element['values']: boolean_row = html.DIV(Class='boolean-row') boolean_row <= html.BUTTON( 'True', Class=f'cue show boolean secondary primary-{key}') # boolean_row <= w.label(f'{name}: {value}', typo='body1', Class=f'boolean-text cue show secondary primary-{key}') boolean_row <= html.BUTTON( f'{name}: {value}', Class=f'secondary gui-value show primary-{key}') boolean_row <= html.BUTTON( 'False', Class=f'cue show boolean secondary primary-{key}') boolean_area <= boolean_row boolean_area <= boolean_row self.secondary_area <= boolean_area button_back = html.BUTTON(BACK_ARROW, Class=f'cue show secondary back-arrow') button_back.bind('click', lambda evt: self.show('primary')) self.secondary_area <= button_back self.stimuli_area <= self.primary_area self.stimuli_area <= self.secondary_area self.dashboard <= w.label('P300 GUI', typo='headline4') self.dashboard <= w.slider('Stimuli duration', min=50, max=300, step=10, value=100, id='stimuli_duration') self.dashboard <= w.slider('Stimuli interval', min=100, max=1000, step=10, value=350, id='stimuli_interval') self.dashboard <= w.button('Start stimlui', on_click=self.blink) self.show('primary')
def blink_element(self, item): """""" item.class_name += ' blink' timer.set_timeout(lambda: self.blink_element_off(item), w.get_value('stimuli_duration'))