diff --git a/obci/configs/multiplexer.rules b/obci/configs/multiplexer.rules index 70c8f426..0325c443 100644 --- a/obci/configs/multiplexer.rules +++ b/obci/configs/multiplexer.rules @@ -1024,6 +1024,11 @@ type { whom: ALL report_delivery_error: false } + to { + peer: "LOGIC_FEEDBACK" + whom: ALL + report_delivery_error: false + } } type { diff --git a/obci/control/gui/presets/budzik.ini b/obci/control/gui/presets/budzik.ini index 815cac26..9395680f 100644 --- a/obci/control/gui/presets/budzik.ini +++ b/obci/control/gui/presets/budzik.ini @@ -20,3 +20,95 @@ info=Run eyetracker (sample2d) with eyetracker signal saver(sample2d) launch_file=scenarios/budzik/prototypes/etr_ws_signal_saver_sample2d.ini public_params= category=Prototypes + +[P300 offline calibration] +info=run p300 calibration on recorded signal +launch_file=scenarios/budzik/prototypes/p300calibrate_offline.ini +public_params= +category=Prototypes P300 + +[P300 online test maze] +info=run p300 on calibrated classifier +launch_file=scenarios/budzik/prototypes/p300_labyrinth_dummy.ini +public_params= +category=Prototypes P300 + +[P300 synthetic online calibration] +info=run p300 calibration on synthetic signal online +launch_file=scenarios/budzik/prototypes/p300calibrate_synthetic_online.ini +public_params= +category=Prototypes P300 + +[P300 online synthetic test generated data] +info=run interactive synthetic test +launch_file=scenarios/budzik/prototypes/p300_synthetic_test_online.ini +public_params= +category=Prototypes P300 + +[P300 online synthetic test using real data] +info=run interactive synthetic test target and nontarget epochs from real EEG signal +launch_file=scenarios/budzik/prototypes/p300_online_synthetic_real_data_test.ini +public_params= +category=Prototypes P300 + +[P300 online labirynth all modalities] +info=run interactive labirynth P300 on dummy amp with 3 modalities +launch_file=scenarios/budzik/prototypes/modal_p300/p300_labyrinth_dummy.ini +public_params= +category=Prototypes P300 + + +[P300 online labirynth visual audio text highlight by image] +info=run interactive labirynth P300 on dummy amp with 2 modalities +launch_file=scenarios/budzik/prototypes/visual_audio_image_highlight.ini +public_params= +category=Prototypes P300 + +[P300 online labirynth visual audio images no text] +info=run interactive labirynth P300 on dummy amp with 2 modalities +launch_file=scenarios/budzik/prototypes/visual_audio_no_text_image_highlight.ini +public_params= +category=Prototypes P300 + +[P300 visual 2 classes bci dummy] +info=run interactive p300 2 class bci with faces as highlight +launch_file=scenarios/budzik/prototypes/P300_visual_2_class_budzik.ini +public_params= +category=Prototypes P300 visual bci + +[P300 visual 2 classes bci calibration dummy] +info=run 2 class bci calibration with faces as highlight +launch_file=scenarios/budzik/prototypes/P300_visual_2_class_budzik_calibration.ini +public_params= +category=Prototypes P300 visual bci + +[P300 visual 2 classes bci] +info=run interactive p300 2 class bci with faces as highlight +launch_file=scenarios/budzik/prototypes/P300_visual_2_class_budzik_amp.ini +public_params= +category=Prototypes P300 visual bci + +[P300 visual 8 classes bci] +info=run interactive p300 8 class bci with faces as highlight +launch_file=scenarios/budzik/prototypes/p300_visual_8_classes.ini +public_params= +category=Prototypes P300 visual bci + + +[P300 visual 2 classes bci calibration] +info=run 2 class bci calibration with faces as highlight +launch_file=scenarios/budzik/prototypes/P300_visual_2_class_budzik_calibration_amp.ini +public_params= +category=Prototypes P300 visual bci + +[P300 haptic 2 classes bci] +info=run interactive p300 2 class bci with haptic stim +launch_file=scenarios/budzik/prototypes/P300_haptic_2_class_budzik_amp.ini +public_params= +category=Prototypes P300 haptic bci + +[P300 haptic 2 classes bci calibration] +info=run 2 class bci calibration with haptic stim +launch_file=scenarios/budzik/prototypes/P300_haptic_2_class_budzik_calibration_amp.ini +public_params= +category=Prototypes P300 haptic bci diff --git a/obci/devices/haptics/haptics_stim_test_logic_peer.py b/obci/devices/haptics/haptics_stim_test_logic_peer.py index ec3bb2f8..e946d61b 100644 --- a/obci/devices/haptics/haptics_stim_test_logic_peer.py +++ b/obci/devices/haptics/haptics_stim_test_logic_peer.py @@ -68,6 +68,25 @@ def generate_test_messages(self): self.logger.info('RUNNING! S2') time.sleep(4) + msg = variables_pb2.Variable() + msg.key = 'S' + msg.value = '3:0.5' + self.conn.send_message(message=msg.SerializeToString(), + type=types.HAPTIC_CONTROL_MESSAGE, + flush=True) + self.logger.info('RUNNING! S3') + time.sleep(4) + + + msg = variables_pb2.Variable() + msg.key = 'S' + msg.value = '4:0.5' + self.conn.send_message(message=msg.SerializeToString(), + type=types.HAPTIC_CONTROL_MESSAGE, + flush=True) + self.logger.info('RUNNING! S4') + time.sleep(4) + msg = variables_pb2.Variable() msg.key = 'S' msg.value = '1,2:1.5,2.5' diff --git a/obci/gui/ugm/blinking/ugm_blinking_count_manager.py b/obci/gui/ugm/blinking/ugm_blinking_count_manager.py index be9823f2..17b9968f 100644 --- a/obci/gui/ugm/blinking/ugm_blinking_count_manager.py +++ b/obci/gui/ugm/blinking/ugm_blinking_count_manager.py @@ -2,7 +2,7 @@ # -*- coding: utf-8 -*- # Author: # Mateusz Kruszyński - +# Marian Dovgialo from obci.utils import sequence_provider class DummyProvider(object): def get_value(self): diff --git a/obci/gui/ugm/blinking/ugm_blinking_ugm_manager.py b/obci/gui/ugm/blinking/ugm_blinking_ugm_manager.py index 107353af..5a2a449e 100644 --- a/obci/gui/ugm/blinking/ugm_blinking_ugm_manager.py +++ b/obci/gui/ugm/blinking/ugm_blinking_ugm_manager.py @@ -4,6 +4,7 @@ # Mateusz Kruszyński from obci.gui.ugm import ugm_config_manager +import os.path class _SingleUgmManager(object): def __init__(self, configs): mgr = ugm_config_manager.UgmConfigManager(configs.get_param('ugm_config')) @@ -111,9 +112,169 @@ def get_unblink_ugm(self, area_id): +class _SingleTextImageOddballUgmManager(object): + '''Ugm config manager for blinks - text with synchronous nontarget + blinks and additional target oddball - image. + + BCI design maximising efficiency based on studies: + Jin, Jing, et al. "A P300 Brain–Computer Interface Based on a + Modification of the Mismatch Negativity Paradigm." + International journal of neural systems 25.03 (2015): 1550011. + + Kaufmann, Tobias, et al. "Face stimuli effectively + prevent brain–computer interface inefficiency in patients with + neurodegenerative disease." + Clinical Neurophysiology 124.5 (2013): 893-900. + + ''' + def __init__(self, configs): + mgr = ugm_config_manager.UgmConfigManager(configs.get_param('ugm_config')) + start_id = int(configs.get_param('blink_ugm_id_start')) + count = int(configs.get_param('blink_ugm_id_count')) + dec_count = int(configs.get_param('blink_id_count')) + active_field_ids = [int(field) for field in configs.get_param('active_field_ids').split(';')] + target_image_path = configs.get_param('target_image_path') + image_fields_id_offset = int(configs.get_param('image_fields_id_offset')) + + assert(start_id >= 0) + assert(count >= 0) + assert(count == dec_count) + + self.blink_ugm = [] + self.unblink_ugm = [] + self.half_blink_ugm = [] + self.half_unblink_ugm = [] + #create blinks and unblinks for every field + for dec in active_field_ids:#range(count): + new_blink_cfgs = [] + new_unblink_cfgs = [] + cfg_target = mgr.get_config_for(start_id+dec+image_fields_id_offset) + new_blink_cfgs.append({'id':cfg_target['id'], + 'image_path':target_image_path + }) + new_unblink_cfgs.append({'id':cfg_target['id'], + 'image_path':'' + }) + #highlight every nontarget field: + + for ndec in active_field_ids: + cfg = mgr.get_config_for(start_id+ndec) + half_blink = {'id':cfg['id'], + configs.get_param('blink_ugm_key'):configs.get_param('blink_ugm_value') + } + new_blink_cfgs.append(half_blink) + self.half_blink_ugm.append(half_blink) + half_unblink = {'id':cfg['id'], + configs.get_param('blink_ugm_key'):cfg[configs.get_param('blink_ugm_key')] + } + new_unblink_cfgs.append(half_unblink) + self.half_unblink_ugm.append(half_unblink) + self.blink_ugm.append(new_blink_cfgs) + self.unblink_ugm.append(new_unblink_cfgs) + #creating half blink + + + def get_blink_ugm(self, area_id): + if area_id is not None: + return self.blink_ugm[area_id] + else: + return self.half_blink_ugm + + def get_unblink_ugm(self, area_id): + if area_id is not None: + return self.unblink_ugm[area_id] + else: + return self.half_unblink_ugm + + +class _SingleImageOddballUgmManager(_SingleTextImageOddballUgmManager): + '''Ugm config manager for blinks - images with synchronous nontarget + blinks and additional target oddball - image - another image. + + BCI design maximising efficiency based on studies: + Jin, Jing, et al. "A P300 Brain–Computer Interface Based on a + Modification of the Mismatch Negativity Paradigm." + International journal of neural systems 25.03 (2015): 1550011. + + Kaufmann, Tobias, et al. "Face stimuli effectively + prevent brain–computer interface inefficiency in patients with + neurodegenerative disease." + Clinical Neurophysiology 124.5 (2013): 893-900. + + ''' + def __init__(self, configs): + mgr = ugm_config_manager.UgmConfigManager(configs.get_param('ugm_config')) + start_id = int(configs.get_param('blink_ugm_id_start')) + count = int(configs.get_param('blink_ugm_id_count')) + dec_count = int(configs.get_param('blink_id_count')) + active_field_ids = [int(field) for field in configs.get_param('active_field_ids').split(';')] + images_folder = configs.get_param('images_path') + images_extension = configs.get_param('images_extension') + + assert(start_id >= 0) + assert(count >= 0) + assert(count == dec_count) + + self.blink_ugm = [] + self.unblink_ugm = [] + self.half_unblink_ugm = [] + self.half_blink_ugm = [] + #create blinks and unblinks for every field + for dec in active_field_ids: + new_blink_cfgs = [] + new_unblink_cfgs = [] + + cfg_target = mgr.get_config_for(start_id+dec) + targ_image = os.path.join(images_folder, + '{}t.{}'.format(dec, images_extension)) + idle_image = os.path.join(images_folder, + '{}i.{}'.format(dec, images_extension)) + new_blink_cfgs.append({'id':cfg_target['id'], + 'image_path':targ_image + }) + new_unblink_cfgs.append({'id':cfg_target['id'], + 'image_path':idle_image + }) + #highlight every nontarget field: + + for ndec in active_field_ids: + #change only nontarget, here this is important + if ndec!=dec: + + high_image = os.path.join(images_folder, + '{}n.{}'.format(ndec, images_extension)) + idle_image = os.path.join(images_folder, + '{}i.{}'.format(ndec, images_extension)) + cfg = mgr.get_config_for(start_id+ndec) + new_blink_cfgs.append({'id':cfg['id'], + 'image_path':high_image + }) + new_unblink_cfgs.append({'id':cfg['id'], + 'image_path':idle_image + }) + + self.blink_ugm.append(new_blink_cfgs) + self.unblink_ugm.append(new_unblink_cfgs) + #creating half blinks: + for ndec in active_field_ids: + high_image = os.path.join(images_folder, + '{}n.{}'.format(ndec, images_extension)) + idle_image = os.path.join(images_folder, + '{}i.{}'.format(ndec, images_extension)) + cfg = mgr.get_config_for(start_id+ndec) + self.half_blink_ugm.append({'id':cfg['id'], + 'image_path':high_image + }) + self.half_unblink_ugm.append({'id':cfg['id'], + 'image_path':idle_image + }) + + MGRS = { 'single':_SingleUgmManager, - 'classic':_ClassicUgmManager + 'classic':_ClassicUgmManager, + 'singletextimageoddball':_SingleTextImageOddballUgmManager, + 'singleimageoddball':_SingleImageOddballUgmManager, } class UgmBlinkingUgmManager(object): diff --git a/obci/gui/ugm/blinking/ugm_modal_blinking_engine.py b/obci/gui/ugm/blinking/ugm_modal_blinking_engine.py new file mode 100644 index 00000000..c8cccece --- /dev/null +++ b/obci/gui/ugm/blinking/ugm_modal_blinking_engine.py @@ -0,0 +1,220 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# Author: +# Marian Dovgialo + +# requires pyo for sound +from __future__ import print_function +from ugm_blinking_engine import UgmBlinkingEngine +import sys + +from obci.devices.haptics.HapticsControl import HapticStimulator +from obci.utils import context as ctx +from obci.gui.ugm import ugm_engine +from PyQt4 import QtCore +import time +import os.path +import random + +HALFBLINKID=-1 + +class pygameSoundCompat: + def __init__(self, sound): + self.sound = sound + def out(self): + self.sound.play() + +class UgmModalBlinkingEngine(UgmBlinkingEngine): + """A class representing ugm application. It is supposed to fire ugm, + receive messages from outside (UGM_UPDATE_MESSAGES) and send`em to + ugm pyqt structure so that it can refresh. + Can be used to evoke P300 of different modalities + (visual, haptic, auditory, combinations). + """ + def __init__(self, p_config_manager, p_connection, + context=ctx.get_dummy_context('UgmBlinkingEngine'), + modalities=['visual',]): + """Store config manager. + Args: + Modalities: modalities used for stimulation, list of strings. + available options: 'visual', 'auditory', 'haptic' + """ + + super(UgmModalBlinkingEngine, self).__init__(p_config_manager, + p_connection, + context) + self.visual = 'visual' in modalities + self.haptic = 'haptic' in modalities + self.auditory = 'auditory' in modalities + + #must be here or else they connect to parent class methods + #~ self._blink_timer = QtCore.QTimer(self) + #~ self._blink_timer.setSingleShot(True) + #~ self._blink_timer.connect(self._blink_timer, QtCore.SIGNAL("timeout()"), self._blink) + + #~ self._unblink_timer = QtCore.QTimer(self) + #~ self._unblink_timer.setSingleShot(True) + #~ self._unblink_timer.connect(self._unblink_timer, QtCore.SIGNAL("timeout()"), self._unblink) + + #~ self._stop_timer = QtCore.QTimer(self) + #~ self._stop_timer.setSingleShot(True) + #~ self._stop_timer.connect(self._stop_timer, QtCore.SIGNAL("timeout()"), self._stop) + + + def initpyo(self, soundfiles): + self.context['logger'].info('initialising pyo audio backend') + try: + import pyo + except ImportError: + print ('ERROR no sound library.\n\t\t Installl pyo!\n\t\tsudo apt-get install python-pyo') + sys.exit(1) + self.audio_server = pyo.Server(audio='pa') + self.audio_server.boot() + while not self.audio_server.getIsBooted(): + time.sleep(1) + self.context['logger'].info('audio server bootup'+str(self.audio_server.getIsBooted())) + self.audio_server.boot() + self.audio_server.start() + while not self.audio_server.getIsStarted(): + time.sleep(1) + self.audio_server.start() + time.sleep(2) + sounds = [pyo.SfPlayer(os.path.expanduser(f)) for f in soundfiles] + assert len(soundfiles) == len(self._active_ids) + assert len(sounds) == len(self._active_ids) + self._sounds = dict(zip(self._active_ids, sounds)) + + def initpygame(self, soundfiles, pygame_buffor): + self.context['logger'].info('initialising pygame audio backend') + + try: + import pygame + except ImportError: + print ('ERROR no sound library.\n\t\t Installl pygame!\n\t\tsudo apt-get install python-pygame') + sys.exit(1) + + pygame.mixer.init(44100, -16, 2, pygame_buffor) + sounds = [pygame.mixer.Sound(os.path.expanduser(f)) for f in soundfiles] + soundscompat = [pygameSoundCompat(i) for i in sounds] + assert len(soundfiles) == len(self._active_ids) + assert len(sounds) == len(self._active_ids) + self._sounds = dict(zip(self._active_ids, soundscompat)) + + + def _init_auditory(self, configs): + + soundfiles = configs.get_param('soundfiles').split(';') + self.soundbackend = configs.get_param('soundbackend') + pygame_buffor = int(configs.get_param('pygamebuffor')) + if self.soundbackend == 'pyo': + self.initpyo(soundfiles) + elif self.soundbackend == 'pygame': + self.initpygame(soundfiles, pygame_buffor) + self.context['logger'].info('soundfiles: {}'.format(soundfiles)) + + def _init_haptic(self, configs): + ids = configs.get_param("haptic_device").split(":") + vid, pid = [int(i, base=16) for i in ids] + self.stimulator = HapticStimulator(vid, pid) + channel_map = (int(i) for i in configs.get_param('haptic_channels_map').split(';')) + self._haptic_map = dict(zip(self._active_ids, channel_map)) + self._haptic_duration = float(configs.get_param('haptic_duration')) + + def _schedule_blink(self, start_time): + '''Schedule the next blink with possibility of "half blink"''' + + #do halfblinks sometimes + if random.random()= 0: + self._blinks_count -= 1 + #and half blinks don't need to be sent + self.connection.send_blink(self._curr_blink_id, update_time) + elif self._send_halfblinks: + self.connection.send_blink(HALFBLINKID, update_time) + + t = 1000*(self._blink_duration - (time.time() - start_time)) + if t < 0: + t = 0.0 + self.context['logger'].warning("BLINKER WARNING: blink duration to short for that computer ...") + self._unblink_timer.start(t) + + + def _unblink(self): + start_time = time.time() + if self.visual: + self.update_from(self._curr_unblink_ugm) + update_time = time.time() + if self._blinks_count == 0 or self.STOP: + self.STOP = False + curr_time = self.time_mgr.get_time() + for m in self.mgrs: + m.reset() + self._stop_timer.start(1000*(curr_time - (time.time()-start_time))) + else: + self._schedule_blink(start_time) + + +if __name__ == '__main__': + ugm_engine.run() + diff --git a/obci/gui/ugm/blinking/ugm_modal_blinking_engine_peer.ini b/obci/gui/ugm/blinking/ugm_modal_blinking_engine_peer.ini new file mode 100644 index 00000000..002a82cc --- /dev/null +++ b/obci/gui/ugm/blinking/ugm_modal_blinking_engine_peer.ini @@ -0,0 +1,89 @@ +[local_params] +; engin params ************************* +internal_ip=127.0.0.1 +internal_port= +use_tagger=0 +ugm_config=speller_config_8 + + +; blinking engine params *************** +;common to all modalities +modalities=visual;auditory;haptic +;length of visual stimulation, also time of trial epoch before break kicks in +blink_duration=0.1 +running_on_start=1 + +;auditory +;should be in order of active_field_ids +soundfiles=~/dataset/sounds/1.wav;~/dataset/sounds/2.wav;~/dataset/sounds/3.wav +;available backends: pyo pygame +soundbackend=pyo +;try to keep it at minimum, while the sound doesnt get distorted (must be power of 2) +pygamebuffor=256 +;haptic +haptic_duration=0.1 +haptic_device=0403:6010 +;in order of active_field_ids +haptic_channels_map=1;2;3 + + +; time manager +blink_min_break=0.1 +blink_max_break=0.1 + +; count manager +blink_count_type=inf +; inf, random, random_sequential, sequential +blink_count_min=10 +blink_count_max=15 + +; id manager +blink_id_type=random_sequential +; sequential, random, random_sequential +blink_id_count=8 + +; ugm manager +blink_ugm_id_start=101 +blink_ugm_id_count=8 +blink_id_count=8 +blink_ugm_key=color +blink_ugm_value=#00cb21 +blink_ugm_type=single +; +active_field_ids = 0;1;2;3;4;5;6;7 +; single, classic, singletextimageoddball, singleimageoddball +;single - simple blinks +;classig - blinks in groups (rows, columns) +;singletextimageoddball - flash every text field, but targets are +;flashed by image. Behaves like single +;singleimageoddball - the same as above, but uses images instead of text + +; classic... +blink_ugm_row_count=2 +blink_ugm_col_count=4 + +;for highlighting by image (singletextimageoddball): +target_image_path=obci.gui.ugm.resources.bci.png +;text fields are overlaid with image fields ids of image fields +; are offsetted by some integer +; id_image = id_text + offset +image_fields_id_offset=1000 + +;for images and highlighting by image (singleimageoddball): +;images must be named same as active_field_ids adding state and extension: +; there are 3 states - idle i, nontarget n and target t +; ex. for image in field 0 there would be required images: +;0i.png 0t.png 0n.png +; in the "images_path" folder +;no need for offset, but blink_ugm_id_start should point to image field +images_path= +images_extension= + + +;singletextimageoddball and singleimageoddball support "half blinks" +;you can set probability of target blink any target blink and do +;"half blinks" in meantime +global_target_proba=1.0 +;send nontarget blink events +;will be sent with id -1 +send_halfblinks=1 diff --git a/obci/gui/ugm/blinking/ugm_modal_blinking_engine_peer.py b/obci/gui/ugm/blinking/ugm_modal_blinking_engine_peer.py new file mode 100644 index 00000000..1889304c --- /dev/null +++ b/obci/gui/ugm/blinking/ugm_modal_blinking_engine_peer.py @@ -0,0 +1,60 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# Author: +# Mateusz Kruszyński +# Marian Dovgialo + +import sys +import thread, os + +from multiplexer.multiplexer_constants import peers, types +from obci.control.peer.configured_client import ConfiguredClient + +from obci.configs import settings, variables_pb2 +from obci.utils import context as ctx +from obci.gui.ugm import ugm_internal_server +from obci.gui.ugm import ugm_config_manager +from obci.gui.ugm.blinking import ugm_modal_blinking_engine +from obci.gui.ugm.blinking import ugm_blinking_connection +from obci.utils.openbci_logging import log_crash + +class DummyClient(object): + def __init__(self, params): + self.params = params + def get_param(self, key): + return self.params[key] + +class UgmModalBlinkingEnginePeer(ConfiguredClient): + @log_crash + def __init__(self, addresses): + super(UgmModalBlinkingEnginePeer, self).__init__(addresses=addresses, type=peers.UGM_ENGINE_PEER) + context = ctx.get_new_context() + context['logger'] = self.logger + connection = ugm_blinking_connection.UgmBlinkingConnection(settings.MULTIPLEXER_ADDRESSES, + context) + + _modalities = self.config.get_param('modalities').split(';') + ENG = ugm_modal_blinking_engine.UgmModalBlinkingEngine( + ugm_config_manager.UgmConfigManager(self.config.get_param('ugm_config')), + connection, + context, + _modalities) + ENG.set_configs(DummyClient(self.config.param_values())) + srv = ugm_internal_server.UdpServer( + ENG, + self.config.get_param('internal_ip'), + int(self.config.get_param('use_tagger')), + context + ) + self.set_param('internal_port', str(srv.socket.getsockname()[1])) + thread.start_new_thread( + srv.run, + () + ) + self.ready() + ENG.run() + +if __name__ == "__main__": + UgmModalBlinkingEnginePeer(settings.MULTIPLEXER_ADDRESSES) + #assume closing ugm should stop all other peers... + sys.exit(1) diff --git a/obci/gui/ugm/configs/budzik_visual_p300_2class.ugm b/obci/gui/ugm/configs/budzik_visual_p300_2class.ugm new file mode 100644 index 00000000..8c979462 Binary files /dev/null and b/obci/gui/ugm/configs/budzik_visual_p300_2class.ugm differ diff --git a/obci/gui/ugm/configs/budzik_visual_p300_8class.ugm b/obci/gui/ugm/configs/budzik_visual_p300_8class.ugm new file mode 100644 index 00000000..062cf6f1 Binary files /dev/null and b/obci/gui/ugm/configs/budzik_visual_p300_8class.ugm differ diff --git a/obci/gui/ugm/configs/labyrinth_face_highlight.ugm b/obci/gui/ugm/configs/labyrinth_face_highlight.ugm new file mode 100644 index 00000000..0491a8c2 Binary files /dev/null and b/obci/gui/ugm/configs/labyrinth_face_highlight.ugm differ diff --git a/obci/gui/ugm/resources/einstein.png b/obci/gui/ugm/resources/einstein.png new file mode 100644 index 00000000..9a6a6100 Binary files /dev/null and b/obci/gui/ugm/resources/einstein.png differ diff --git a/obci/interfaces/bci/analysis_master.py b/obci/interfaces/bci/analysis_master.py index a080bb49..22635ed1 100644 --- a/obci/interfaces/bci/analysis_master.py +++ b/obci/interfaces/bci/analysis_master.py @@ -126,6 +126,7 @@ def learn(self, classifier, chunk, target): @log_crash def __init__(self, addresses, type=peers.ANALYSIS): super(AnalysisMaster, self).__init__(addresses=addresses, type=type) + self.logger.info('Initialising parameters') # initialize parameters of the subclass self.init_params() channel_count = len(self.config.get_param('channel_names').split(';')) @@ -217,6 +218,7 @@ def handle_message(self, mxmsg): # we have received a single blink data = variables_pb2.Blink() data.ParseFromString(mxmsg.message) + self.logger.debug('Got blink: {}'.format(data)) self.buffer.handle_blink(data) else: diff --git a/obci/interfaces/bci/p300_MD/__init__.py b/obci/interfaces/bci/p300_MD/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/obci/interfaces/bci/p300_MD/helper_functions.py b/obci/interfaces/bci/p300_MD/helper_functions.py new file mode 100644 index 00000000..b6b72c64 --- /dev/null +++ b/obci/interfaces/bci/p300_MD/helper_functions.py @@ -0,0 +1,504 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# based on obci.analysis.p300.analysis_offline +# Marian Dovgialo +from scipy import zeros, diag, dot, ones +from scipy import linalg +import numpy as np +import pylab as pb +from scipy import signal +import scipy.stats +import copy +from obci.analysis.obci_signal_processing.signal import read_info_source +from obci.analysis.obci_signal_processing.signal import read_data_source +from obci.analysis.obci_signal_processing.tags import read_tags_source +from obci.analysis.obci_signal_processing import read_manager +from obci.analysis.obci_signal_processing.smart_tags_manager import SmartTagsManager +from obci.analysis.obci_signal_processing.tags.smart_tag_definition import SmartTagDurationDefinition + +def target_tags_func(tag): + return tag['desc'][u'index']==tag['desc'][u'target'] + +def nontarget_tags_func(tag): + return tag['desc'][u'index']!=tag['desc'][u'target'] + +def get_epochs_fromfile(ds, start_offset=-0.1,duration=2.0, + filter=None, montage=None, + drop_chnls = [ u'AmpSaw', u'DriverSaw', u'trig1', u'trig2'], + target_tags_func = target_tags_func, + nontarget_tags_func = nontarget_tags_func, + tag_name = u'blink' + ): + '''For offline calibration and testing, load target and nontarget + epochs using obci read_manager. + Args: + ds: dataset file name without extension. + start_offset: baseline in negative seconds, + duration: duration of the epoch (including baseline), + filter: list of [wp, ws, gpass, gstop] for scipy.signal.iirdesign + in Hz, Db, or None if no filtering is required + montage: list of ['montage name', ...] ...-channel names if required + montage name can be 'ears', 'csa', 'custom' + ears require 2 channel names for ear channels + custom requires list of reference channel names + target_tags_func: must return True for provided tag if tag + defines a target + nontarget_tags_func: must return False for provided tag if tag + defines a target + tag_name: tag name to be considered, if you want to use all + tags use None + Return: two lists of smart tags: target_tags, nontarget_tags''' + eeg_rm = read_manager.ReadManager(ds+'.xml', ds+'.raw', ds+'.tag') + + + if filter: + eeg_rm = mgr_filter(eeg_rm, filter[0], filter[1],filter[2], + filter[3], ftype='cheby2', use_filtfilt=True) + if montage: + if montage[0] == 'ears': + eeg_rm = montage_ears(eeg_rm, montage[1], montage[2]) + elif montage[0] == 'csa': + eeg_rm = montage_csa(eeg_rm) + elif montage[0] == 'custom': + eeg_rm = montage_custom(eeg_rm, montage[1:]) + else: + raise Exception('Unknown montage') + eeg_rm = exclude_channels(eeg_rm, drop_chnls) + + + tag_def = SmartTagDurationDefinition(start_tag_name=tag_name, + start_offset=start_offset, + end_offset=0.0, + duration=duration) + stags = SmartTagsManager(tag_def, '', '' ,'', p_read_manager=eeg_rm) + target_tags = stags.get_smart_tags(p_func = target_tags_func, ) + nontarget_tags = stags.get_smart_tags(p_func = nontarget_tags_func) + + return target_tags, nontarget_tags + +def evoked_from_smart_tags(tags, chnames, bas = -0.1): + ''' + Args: + tags: smart tag list, to average + chnames: list of channels to use for averaging, + bas: baseline (in negative seconds)''' + min_length = min(i.get_samples().shape[1] for i in tags) + # really don't like this, but epochs generated by smart tags can vary in length by 1 sample + channels_data = [] + Fs = float(tags[0].get_param('sampling_frequency')) + for i in tags: + data = i.get_channels_samples(chnames)[:,:min_length] + for nr, chnl in enumerate(data): + data[nr] = chnl - np.mean(chnl[0:-Fs*bas])# baseline correction + if np.max(np.abs(data))<4000: + channels_data.append(data) + + return np.mean(channels_data, axis=0), scipy.stats.sem(channels_data, axis=0) + + +def evoked_pair_plot_smart_tags(tags1, tags2, chnames=['O1', 'O2', 'Pz', 'PO7', 'PO8', 'PO3', 'PO4', 'Cz',], + start_offset=-0.1, labels=['target', 'nontarget'], show= True): + '''debug evoked potential plot, + pairwise comparison of 2 smarttag lists, + blocks thread + Args: + chnames: channels to plot + start_offset: baseline in seconds''' + ev1, std1 = evoked_from_smart_tags(tags1, chnames, start_offset) + ev2, std2 = evoked_from_smart_tags(tags2, chnames, start_offset) + Fs = float(tags1[0].get_param('sampling_frequency')) + time1 = np.linspace(0+start_offset, ev1.shape[1]/Fs+start_offset, ev1.shape[1]) + time2 = np.linspace(0+start_offset, ev2.shape[1]/Fs+start_offset, ev2.shape[1]) + fig = pb.figure() + for nr, i in enumerate(chnames): + ax = fig.add_subplot( (len(chnames)+1)/2, 2, nr+1) + + ax.plot(time1, ev1[nr], 'r',label = labels[0]+' N:{}'.format(len(tags1))) + ax.fill_between(time1, ev1[nr]-std1[nr], ev1[nr]+std1[nr], + color = 'red', alpha=0.3, ) + ax.plot(time2, ev2[nr], 'b', label = labels[1]+' N:{}'.format(len(tags2))) + ax.fill_between(time2, ev2[nr]-std2[nr], ev2[nr]+std2[nr], + color = 'blue', alpha=0.3) + + ax.set_title(i) + ax.legend() + + if show: + pb.show() + return fig + + + +def mgr_filter(mgr, wp, ws, gpass, gstop, analog=0, ftype='ellip', output='ba', unit='hz', use_filtfilt=False, meancorr=1.0): + if unit == 'radians': + b,a = signal.iirdesign(wp, ws, gpass, gstop, analog, ftype, output) + elif unit == 'hz': + nyquist = float(mgr.get_param('sampling_frequency'))/2.0 + try: + wp = wp/nyquist + ws = ws/nyquist + except TypeError: + wp = [i/nyquist for i in wp] + ws = [i/nyquist for i in ws] + + b,a = signal.iirdesign(wp, ws, gpass, gstop, analog, ftype, output) + if use_filtfilt: + from scipy.signal import filtfilt + #samples_source = read_data_source.MemoryDataSource(mgr.get_samples(), False) + for i in range(int(mgr.get_param('number_of_channels'))): + print("FILT FILT CHANNEL "+str(i)) + mgr.get_samples()[i,:] = signal.filtfilt(b, a, mgr.get_samples()[i]-np.mean(mgr.get_samples()[i])*meancorr) + samples_source = read_data_source.MemoryDataSource(mgr.get_samples(), False) + else: + print("FILTER CHANNELs") + filtered = signal.lfilter(b, a, mgr.get_samples()) + print("FILTER CHANNELs finished") + samples_source = read_data_source.MemoryDataSource(filtered, True) + + info_source = copy.deepcopy(mgr.info_source) + tags_source = copy.deepcopy(mgr.tags_source) + new_mgr = read_manager.ReadManager(info_source, samples_source, tags_source) + return new_mgr +##### + +def leave_channels_array(arr, channels, available): + ''' + :param arr: - 2d array of eeg data channels x samples + :param channels: - channels to leave, + :param available: - channel names in data + ''' + exclude = list(set(available).difference(set(channels))) + new_samples, new_channels = exclude_channels_array( + arr, exclude, available) + return new_samples, new_channels + +def exclude_channels_array(arr, channels, available): + '''arr - 2d array of eeg data channels x samples + channels - channels to exclude, + available - channel names in data''' + exclude = set(channels) + channels = list(set(available).intersection(exclude)) + + ex_channels_inds = [available.index(ch) for ch in channels] + assert(-1 not in ex_channels_inds) + new_samples = zeros((len(available) - len(channels), + len(arr[0]))) + + + new_ind = 0 + new_channels = [] + for ch_ind, ch in enumerate(arr): + if ch_ind in ex_channels_inds: + continue + else: + new_samples[new_ind, :] = ch + new_channels.append(available[ch_ind]) + + new_ind += 1 + return new_samples, new_channels + +def exclude_channels(mgr, channels): + '''exclude all channels in channels list''' + available = set(mgr.get_param('channels_names')) + exclude = set(channels) + channels = list(available.intersection(exclude)) + + new_params = copy.deepcopy(mgr.get_params()) + samples = mgr.get_samples() + new_tags = copy.deepcopy(mgr.get_tags()) + + + ex_channels_inds = [new_params['channels_names'].index(ch) for ch in channels] + assert(-1 not in ex_channels_inds) + + new_samples = zeros((int(new_params['number_of_channels']) - len(channels), + len(samples[0]))) + # Define new samples and params list values + keys = ['channels_names', 'channels_numbers', 'channels_gains', 'channels_offsets'] + keys_to_remove = [] + for k in keys: + try: + #Exclude from keys those keys that are missing in mgr + mgr.get_params()[k] + except KeyError: + keys_to_remove.append(k) + continue + new_params[k] = [] + + for k in keys_to_remove: + keys.remove(k) + new_ind = 0 + for ch_ind, ch in enumerate(samples): + if ch_ind in ex_channels_inds: + continue + else: + new_samples[new_ind, :] = ch + for k in keys: + new_params[k].append(mgr.get_params()[k][ch_ind]) + + new_ind += 1 + + # Define other new new_params + new_params['number_of_channels'] = str(int(new_params['number_of_channels']) - len(channels)) + new_params['number_of_samples'] = str(int(new_params['number_of_samples']) - \ + len(channels)*len(samples[0])) + + + info_source = read_info_source.MemoryInfoSource(new_params) + tags_source = read_tags_source.MemoryTagsSource(new_tags) + samples_source = read_data_source.MemoryDataSource(new_samples) + return read_manager.ReadManager(info_source, samples_source, tags_source) + + +def leave_channels(mgr, channels): + '''exclude all channels except those in channels list''' + chans = copy.deepcopy(mgr.get_param('channels_names')) + for leave in channels: + chans.remove(leave) + return exclude_channels(mgr, chans) + + +def filter(mgr, wp, ws, gpass, gstop, analog=0, ftype='ellip', output='ba', unit='radians', use_filtfilt=False): + if unit == 'radians': + b,a = signal.iirdesign(wp, ws, gpass, gstop, analog, ftype, output) + elif unit == 'hz': + sampling = float(mgr.get_param('sampling_frequency')) + try: + wp = wp/sampling + ws = ws/sampling + except TypeError: + wp = [i/sampling for i in wp] + ws = [i/sampling for i in ws] + + b,a = signal.iirdesign(wp, ws, gpass, gstop, analog, ftype, output) + if use_filtfilt: + import filtfilt + #samples_source = read_data_source.MemoryDataSource(mgr.get_samples(), False) + for i in range(int(mgr.get_param('number_of_channels'))): + print("FILT FILT CHANNEL "+str(i)) + mgr.get_samples()[i,:] = filtfilt.filtfilt(b, a, mgr.get_samples()[i]) + samples_source = read_data_source.MemoryDataSource(mgr.get_samples(), False) + else: + print("FILTER CHANNELs") + filtered = signal.lfilter(b, a, mgr.get_samples()) + print("FILTER CHANNELs finished") + samples_source = read_data_source.MemoryDataSource(filtered, True) + + info_source = copy.deepcopy(mgr.info_source) + tags_source = copy.deepcopy(mgr.tags_source) + new_mgr = read_manager.ReadManager(info_source, samples_source, tags_source) + return new_mgr + +def normalize(mgr, norm): + if norm == 0: + return mgr + new_mgr = copy.deepcopy(mgr) + for i in range(len(new_mgr.get_samples())): + n = linalg.norm(new_mgr.get_samples()[i, :], norm) + new_mgr.get_samples()[i, :] /= n + return new_mgr + + +def downsample(mgr, factor): + assert(factor >= 1) + + + ch_num = len(mgr.get_samples()) + ch_len = len(mgr.get_samples()[0]) + + # To be determined ... + ret_ch_len = 0 + i = 0 + left_inds = [] + + # Determine ret_ch_len - a size of returned channel + while i < ch_len: + left_inds.append(i) + ret_ch_len += 1 + i += factor + + new_samples = array([zeros(ret_ch_len) for i in range(ch_num)]) + for i in range(ch_num): + for j, ind in enumerate(left_inds): + new_samples[i, j] = mgr.get_samples()[i, ind] + + + info_source = copy.deepcopy(mgr.info_source) + info_source.get_params()['number_of_samples'] = str(ret_ch_len*ch_num) + info_source.get_params()['sampling_frequency'] = str(float(mgr.get_param('sampling_frequency'))/factor) + + tags_source = copy.deepcopy(mgr.tags_source) + samples_source = read_data_source.MemoryDataSource(new_samples) + return read_manager.ReadManager(info_source, samples_source, tags_source) + +def montage(mgr, montage_type, **montage_params): + if montage_type == 'common_spatial_average': + return montage_csa(mgr, **montage_params) + elif montage_type == 'ears': + return montage_ears(mgr, **montage_params) + elif montage_type == 'custom': + return montage_custom(mgr, **montage_params) + elif montage_type == 'no_montage': + return mgr + else: + raise Exception("Montage - unknown montaget type: "+str(montage_type)) + +def montage_csa(mgr): + new_samples = get_montage(mgr.get_samples(), + get_montage_matrix_csa(int(mgr.get_param('number_of_channels')))) + info_source = copy.deepcopy(mgr.info_source) + tags_source = copy.deepcopy(mgr.tags_source) + samples_source = read_data_source.MemoryDataSource(new_samples) + return read_manager.ReadManager(info_source, samples_source, tags_source) + +def montage_ears(mgr, l_ear_channel, r_ear_channel): + left_index = mgr.get_param('channels_names').index(l_ear_channel) + right_index = mgr.get_param('channels_names').index(r_ear_channel) + if left_index < 0 or right_index < 0: + raise Exception("Montage - couldn`t find ears channels: "+str(l_ear_channel)+", "+str(r_ear_channel)) + + new_samples = get_montage(mgr.get_samples(), + get_montage_matrix_ears( + int(mgr.get_param('number_of_channels')), + left_index, + right_index + )) + info_source = copy.deepcopy(mgr.info_source) + tags_source = copy.deepcopy(mgr.tags_source) + samples_source = read_data_source.MemoryDataSource(new_samples) + return read_manager.ReadManager(info_source, samples_source, tags_source) + + +def get_channel_indexes(channels, toindex): + '''get list of indexes of channels in toindex list as found in + channels list''' + indexes = [] + for chnl in toindex: + index = channels.index(chnl) + if index<0: + raise Exception("Montage - couldn`t channel: "+str(chnl)) + else: + indexes.append(index) + return indexes + +def montage_custom(mgr, chnls): + '''apply custom montage to manager, by chnls''' + indexes = [] + for chnl in chnls: + print mgr.get_param('channels_names') + index = mgr.get_param('channels_names').index(chnl) + if index<0: + raise Exception("Montage - couldn`t channel: "+str(chnl)) + else: + indexes.append(index) + + new_samples = get_montage(mgr.get_samples(), + get_montage_matrix_custom( + int(mgr.get_param('number_of_channels')), + indexes + )) + info_source = copy.deepcopy(mgr.info_source) + tags_source = copy.deepcopy(mgr.tags_source) + samples_source = read_data_source.MemoryDataSource(new_samples) + return read_manager.ReadManager(info_source, samples_source, tags_source) + +def montage_custom_matrix(mgr, montage_matrix): + new_samples = get_montage(mgr.get_samples(), + montage_matrix) + info_source = copy.deepcopy(mgr.info_source) + tags_source = copy.deepcopy(mgr.tags_source) + samples_source = read_data_source.MemoryDataSource(new_samples) + return read_manager.ReadManager(info_source, samples_source, tags_source) + +def get_montage(data, montage_matrix): + """ + montage_matrix[i] = linear transformation of all channels to achieve _new_ channel i + data[i] = original data from channel i + + >>> montage_matrix = np.array([[ 1. , -0.25, -0.25, -0.25, -0.25], [-0.25, 1. , -0.25, -0.25, -0.25], [-0.25, -0.25, 1. , -0.25, -0.25],[-0.25, -0.25, -0.25, 1. , -0.25], [-0.25, -0.25, -0.25, -0.25, 1. ]]) + >>> data = np.array(5 * [np.ones(10)]) + >>> montage(data,montage_matrix) + array([[ 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.], + [ 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.], + [ 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.], + [ 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.], + [ 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.]]) + + + """ + + return dot(montage_matrix, data) + + + + +def get_montage_matrix_csa(n): + """ + Return nxn array representing extraction from + every channel an avarage of all other channels. + + >>> get_montage_matrix_avg(5) + array([[ 1. , -0.25, -0.25, -0.25, -0.25], + [-0.25, 1. , -0.25, -0.25, -0.25], + [-0.25, -0.25, 1. , -0.25, -0.25], + [-0.25, -0.25, -0.25, 1. , -0.25], + [-0.25, -0.25, -0.25, -0.25, 1. ]]) + + """ + + factor = -1.0/(n - 1) + mx = ones((n, n)) + for i in range(n): + for j in range(n): + if i != j: + mx[i, j] = factor + return mx + + + +def get_montage_matrix_ears(n, l_ear_index, r_ear_index): + """ + Return nxn array representing extraction from + every channel an avarage of channels l_ear_index + and r_ear_index. + + >>> get_montage_matrix_ears(5, 2, 4) + array([[ 1. , 0. , -0.5, 0. , -0.5], + [ 0. , 1. , -0.5, 0. , -0.5], + [ 0. , 0. , 1. , 0. , 0. ], + [ 0. , 0. , -0.5, 1. , -0.5], + [ 0. , 0. , 0. , 0. , 1. ]]) + """ + + factor = -0.5 + mx = diag([1.0]*n) + for i in range(n): + for j in range(n): + if j in [r_ear_index, l_ear_index] \ + and j != i \ + and not i in [r_ear_index, l_ear_index]: + mx[i, j] = factor + return mx + +def get_montage_matrix_custom(n, indexes): + """ + Return nxn array representing extraction from + every channel an avarage of channels in indexes list + + >>> get_montage_matrix_custom(5, [2, 4]) + array([[ 1. , 0. , -0.5, 0. , -0.5], + [ 0. , 1. , -0.5, 0. , -0.5], + [ 0. , 0. , 1. , 0. , 0. ], + [ 0. , 0. , -0.5, 1. , -0.5], + [ 0. , 0. , 0. , 0. , 1. ]]) + """ + + factor = -1.0/len(indexes) + mx = diag([1.0]*n) + for i in range(n): + for j in range(n): + if j in indexes \ + and j != i \ + and not i in indexes: + mx[i, j] = factor + return mx diff --git a/obci/interfaces/bci/p300_MD/logic_p300_calibration_peer.ini b/obci/interfaces/bci/p300_MD/logic_p300_calibration_peer.ini new file mode 100644 index 00000000..1ff7578b --- /dev/null +++ b/obci/interfaces/bci/p300_MD/logic_p300_calibration_peer.ini @@ -0,0 +1,20 @@ +[local_params] +hi_text=Witamy. Zliczaj pojawianie się twarzy na napisie TAK +bye_text=Dziekujemy. +break_text=Przerwa. Teraz mrugaj. +break_duration=2 +trials_count=17 + +[config_sources] +ugm_engine= +analysis= + +[external_params] +ugm_config=ugm_engine.ugm_config +blink_duration=ugm_engine.blink_duration +target=analysis.calibration_field_index + +[launch_dependencies] +ugm_server= +ugm_engine= +analysis= \ No newline at end of file diff --git a/obci/interfaces/bci/p300_MD/logic_p300_calibration_peer.py b/obci/interfaces/bci/p300_MD/logic_p300_calibration_peer.py new file mode 100644 index 00000000..662ebe4b --- /dev/null +++ b/obci/interfaces/bci/p300_MD/logic_p300_calibration_peer.py @@ -0,0 +1,97 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# Author: +# Mateusz Kruszyński +# Marian Dovgialo + +import os.path, sys, time + +from multiplexer.multiplexer_constants import peers, types +from obci.control.peer.configured_multiplexer_server import ConfiguredMultiplexerServer + +from obci.configs import settings, variables_pb2 +from obci.gui.ugm import ugm_config_manager +from obci.gui.ugm import ugm_helper +from obci.utils import keystroke +from obci.utils import tags_helper + +from obci.acquisition import acquisition_helper + +class LogicP300Calibration(ConfiguredMultiplexerServer): + '''BCI calibration controller''' + def __init__(self, addresses): + super(LogicP300Calibration, self).__init__(addresses=addresses, + type=peers.LOGIC_P300_CALIBRATION) + self.blinking_ugm = ugm_config_manager.UgmConfigManager(self.config.get_param("ugm_config")).config_to_message() + self.hi_text = self.config.get_param("hi_text") + self.bye_text = self.config.get_param("bye_text") + self.break_text = self.config.get_param("break_text") + self.break_duration = float(self.config.get_param("break_duration")) + self.trials_count = int(self.config.get_param("trials_count")) + self.current_target = int(self.config.get_param("target")) + self.blink_duration = float(self.config.get_param("blink_duration")) + + self._trials_counter = self.trials_count + self.ready() + self.begin() + + def handle_message(self, mxmsg): + """Method fired by multiplexer. It conveys decision to logic engine.""" + if (mxmsg.type == types.UGM_ENGINE_MESSAGE): + self._handle_ugm_engine(mxmsg.message) + elif mxmsg.type == types.BLINK_MESSAGE: + self._handle_blink(mxmsg.message) + else: + self.logger.warning("Got unrecognised message type: "+mxmsg.type) + self.no_response() + + def _handle_blink(self, msg): + b = variables_pb2.Blink() + b.ParseFromString(msg) + self.logger.debug("GOT BLINK: "+str(b.timestamp)+" / "+str(b.index)) + tags_helper.send_tag(self.conn, + b.timestamp, b.timestamp+self.blink_duration, "blink", + {"index" : b.index, + "target":self.current_target + }) + + def _handle_ugm_engine(self, msg): + m = variables_pb2.Variable() + m.ParseFromString(msg) + if m.key == "blinking_stopped": + self.logger.info("Got blinking stopped message!") + self._trials_counter -= 1 + if self._trials_counter <= 0: + self.logger.info("All trials passed") + self.end() + else: + self.logger.info("Blinking stopped...") + self.blinking_stopped() + else: + self.logger.info("Got unrecognised ugm engine message: "+str(m.key)) + + def begin(self): + ugm_helper.send_text(self.conn, self.hi_text) + #keystroke.wait([" "]) + time.sleep(5) + self.logger.info("Send begin config ...") + ugm_helper.send_config(self.conn, self.blinking_ugm) + self.logger.info("Send start blinking on begin ...") + ugm_helper.send_start_blinking(self.conn) + + def end(self): + ugm_helper.send_text(self.conn, self.bye_text) + #acquire some more data + time.sleep(2) + acquisition_helper.send_finish_saving(self.conn) + + def blinking_stopped(self): + time.sleep(1) + ugm_helper.send_text(self.conn, self.break_text) + time.sleep(self.break_duration) + ugm_helper.send_config(self.conn, self.blinking_ugm) + time.sleep(1) + ugm_helper.send_start_blinking(self.conn) + +if __name__ == "__main__": + LogicP300Calibration(settings.MULTIPLEXER_ADDRESSES).loop() diff --git a/obci/interfaces/bci/p300_MD/p300_classm.py b/obci/interfaces/bci/p300_MD/p300_classm.py new file mode 100644 index 00000000..54be4f2f --- /dev/null +++ b/obci/interfaces/bci/p300_MD/p300_classm.py @@ -0,0 +1,179 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# P300 classifier mockup +# Marian Dovgialo +from __future__ import print_function +import numpy as np +import scipy.stats +import scipy.signal as ss +from sklearn.externals import joblib +try: + from sklearn.lda import LDA as LinearDiscriminantAnalysis +except ImportError: + from sklearn.discriminant_analysis import LinearDiscriminantAnalysis + +from collections import deque +from obci.interfaces.bci.abstract_classifier import AbstractClassifier +import pickle + +LEARN_EVERY = 20 # relearn every # provided targets + +def _tags_to_array(tags): + '''returns 3D numpy array from OBCI smart tags + epochs x channels x time''' + min_length = min(i.get_samples().shape[1] for i in tags) +# really don't like this, but epochs generated by smart tags can vary in length by 1 sample + array = np.dstack([i.get_samples()[:,:min_length] for i in tags]) + return np.rollaxis(array,2) + +def _remove_artifact_epochs(data, labels): + ''' data - 3D numpy array epoch x channels x time, + labels - list of epochs labels + returns clean data and labels + Provisional version''' + mask = np.ones(len(data), dtype = bool) + for id, i in enumerate(data): + if np.max(np.abs(i-i[:,0][:, None]))>2000: + mask[id]=False + newlabels = [l for l, m in zip(labels, mask) if m] + newdata = data[mask] + return newdata, newlabels + + +def _feature_extraction(data, Fs, bas=-0.1, window=0.4, targetFs=34): + '''data - 3D numpy array epoch x channels x time, + returns spatiotemporal features array epoch x features''' + features = [] + for epoch in data: + features.append(_feature_extraction_singular(epoch, Fs, bas, + window, targetFs)) + return np.array(features) + + + +def _feature_extraction_singular(epoch, Fs, bas=-0.1, + window = 0.5, + targetFs=30,): + '''performs feature extraction on epoch (array channels x time), + Args: + Fs: sampling in Hz + bas: baseline in seconds + targetFs: target sampling in Hz (will be approximated) + window: timewindow after baseline to select in seconds + + Returns: 1D array downsampled, len = downsampled samples x channels + epoch minus mean of baseline, downsampled by factor int(Fs/targetFs) + samples used - from end of baseline to window timepoint + ''' + mean = np.mean(epoch[:, :-bas*Fs], axis=1) + decimation_factor = int(1.0*Fs/targetFs) + selected = epoch[:,-bas*Fs:(-bas+window)*Fs]-mean[:, None] + features = ss.decimate(selected, decimation_factor, axis=1, ftype='fir') + return features.flatten() + +def _feature_reduction_mask(ft, labels, mode): + ''' ft - features 2d array nsamples x nfeatures + labels - nsamples array of labels 0, 1, + mode - 'auto', int + returns - features mask''' + tscore, p = scipy.stats.ttest_ind(ft[labels==1], ft[labels==0]) + if mode == 'auto': + mask = p<0.05 + if mask.sum()<1: + raise Exception('Feature reduction produced zero usable features') + elif isinstance(mode, int): + mask_ind = np.argsort(p)[-mode:] + mask = np.zeros_like(p, dtype=bool) + mask[mask_ind] = True + return mask + + + +class P300EasyClassifier(AbstractClassifier): + '''Easy and modular P300 classifier + attributes" + ''' + + def __init__(self, clf=None, + targetFs=24): + '''Args: + clf: scikit learn type classifier, None if you want to + use standard LDA with shrinkage + targetFS: target sampling rate after downsampling for + feature extraction + ''' + if clf is None: + self.clf = LinearDiscriminantAnalysis(solver = 'lsqr', shrinkage='auto') + self.targetFs = targetFs + self.learning_buffor_features = list() + self.learning_buffor_classes = list() + + + + def classify(self, features): + ''' + Args: + features - 1D vector of extracted features + ''' + #probability of target + return self.clf.predict_proba(features.reshape(1, -1))[0][1] + + def learn(self, chunk, target): + ''' + For online learning thread + + Args: + chunk: numpy 1D features array + target: name of the class + ''' + if target == 'target': + self.learning_buffor_classes.append(1) + else: + self.learning_buffor_classes.append(0) + self.learning_buffor_features.append(chunk) + targets_count = sum(self.learning_buffor_classes) + nontargets_count = sum(i==0 for i in self.learning_buffor_classes) + enough = (targets_count>2 and nontargets_count>2) + if sum(self.learning_buffor_classes)%LEARN_EVERY == 0 and enough: + print('Classifier: fitting clf with new data') + self.clf.fit( + self.learning_buffor_features, + self.learning_buffor_classes, + ) + score = self.clf.score(self.learning_buffor_features, + self.learning_buffor_classes) + print ('Classifier: Test on training set: {}'.format(score)) + + + + def calibrate(self, targets, nontargets, bas=-0.1, window=0.4, Fs=None): + '''Offline learning function + + Args: + + targets, nontargets: 3D arrays (epoch x channel x time) + or list of OBCI smart tags. + If arrays - need to provide Fs + (sampling frequency) in Hz + bas: baseline in seconds(negative), in other words start + offset + window: seconds after event to consider in classification + Fs: needed if 3D numpy array is provided + ''' + + if Fs is None: + Fs = float(targets[0].get_param('sampling_frequency')) + target_data = _tags_to_array(targets) + nontarget_data = _tags_to_array(nontargets) + data = np.vstack((target_data, nontarget_data)) + self.epoch_l = data.shape[2] + labels = np.zeros(len(data)) + labels[:len(target_data)] = 1 + data, labels = _remove_artifact_epochs(data, labels) + features = _feature_extraction(data, Fs, bas, window, self.targetFs) + self.clf.fit(features, labels) + # building a list of features + #will be saved and can be extended in online learning later + self.learning_buffor_classes=[i for i in labels] + self.learning_buffor_features=[i for i in features] + return self.clf.score(features, labels) diff --git a/obci/interfaces/bci/p300_MD/p300_master_peer.ini b/obci/interfaces/bci/p300_MD/p300_master_peer.ini new file mode 100644 index 00000000..b747c359 --- /dev/null +++ b/obci/interfaces/bci/p300_MD/p300_master_peer.ini @@ -0,0 +1,28 @@ +[local_params] +decision_stop_threshold=0.4 +wisdom_path=~/classifier.dump +channels_for_classification=O1;O2;Pz +montage_channels=Cz +baseline=-0.2 +window=0.5 +decision_stop=3 +maximum_to_average=10 +downsample_to=3 +targetFs=24 +;which field is used in online calibration +calibration_field_index= +;if want to run offline calibration provide this file (without .raw): +offline_learning=1 +offline_learning_dataset_path= +hold_after_dec=3 +ignored_blink_ids=-1 + +[config_sources] +amplifier= + +[external_params] +channel_names=amplifier.channel_names +sampling_rate=amplifier.sampling_rate + +[launch_dependencies] +amplifier= diff --git a/obci/interfaces/bci/p300_MD/p300_master_peer.py b/obci/interfaces/bci/p300_MD/p300_master_peer.py new file mode 100644 index 00000000..0f16cb72 --- /dev/null +++ b/obci/interfaces/bci/p300_MD/p300_master_peer.py @@ -0,0 +1,360 @@ +#!/usr/bin/env python2 +# -*- coding: utf-8 -*- +# +# OpenBCI - framework for Brain-Computer Interfaces based on EEG signal +# Project was initiated by Magdalena Michalska and Krzysztof Kulewski +# as part of their MSc theses at the University of Warsaw. +# Copyright (C) 2008-2009 Krzysztof Kulewski and Magdalena Michalska +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +# +# Author: +# Marian Dovgialo + +from obci.configs import settings +from multiplexer.multiplexer_constants import peers, types +from obci.interfaces.bci.analysis_master import AnalysisMaster +from obci.interfaces.bci.p300_MD.p300_classm import P300EasyClassifier +from obci.interfaces.bci.p300_MD.p300_classm import _feature_extraction_singular + +from obci.interfaces.bci.p300_MD.helper_functions import get_montage, get_montage_matrix_custom +from obci.interfaces.bci.p300_MD.helper_functions import leave_channels_array, get_channel_indexes + +from obci.analysis.buffers.auto_blink_buffer import AutoBlinkBuffer +from collections import defaultdict, deque +from operator import itemgetter +from obci.utils.openbci_logging import log_crash +import sys +from obci.interfaces.bci.p300_MD.helper_functions import get_epochs_fromfile +from obci.interfaces.bci.p300_MD.helper_functions import evoked_pair_plot_smart_tags +import numpy as np +import os.path +import pickle +import pylab as pb +import time +from obci.gui.ugm import ugm_helper + +class P300MasterPeer(AnalysisMaster): + '''P300 classifier master peer''' + @log_crash + def __init__(self, addresses): + super(P300MasterPeer, self).__init__(addresses=addresses, + type=peers.P300_ANALYSIS) + + + def _reset_buffors(self): + #probabilities of selected input for single epochs + self.singular_proba_buffor = defaultdict(list) + #probabilities of selected input for cumulative mean + self.averaged_proba_buffor = defaultdict(list) + #features buffor to classify on single epochs or cumulative mean + self.features = defaultdict(list) + #final decision buffor + self.decision_buffor = deque(maxlen = self.decision_stop) + self.hold_time = 1.0 + self.last_dec_timestamp = 0.0 + + def _prepare_chunk(self, chunk): + ''' + Performs channel selection, montage and feature extraction. + + First Montage - look out for average montage and technical channels!! + then channel selection + then feature extraction + + Args: + chunk: numpy 2D data array (channels × samples) + ''' + + chunk_montage = get_montage( + chunk, + self.montage_matrix + ) + chunk_clean_channels, _ = leave_channels_array( + chunk_montage, + self.channels_for_classification, + self.channel_names + ) + + + chunk_ready = _feature_extraction_singular( + chunk_clean_channels, + self.sampling_rate, + self.baseline, + self.window, + self.targetFs, + ) + return chunk_ready + def _send_decision(self, decision): + self.conn.send_message(message = str(decision), type = types.DECISION_MESSAGE, flush=True) + self._reset_buffors() + self.last_dec_timestamp = time.time() + + def add_result(self, blink, probabilities): + ''' + Sends decision if some last decisions from cumulative mean + are the same or a lot of averaging was done + Args: + blink: information contained in a single blink + probabilities (dict): dictionary of {target: probability} + ''' + #planning for future + if probabilities: + self.singular_proba_buffor[blink.index].append( + probabilities['targetSingle'] + ) + self.averaged_proba_buffor[blink.index].append( + probabilities['targetCMean'] + ) + last_single = [blink.index, probabilities['targetSingle']] + last_mean = [blink.index, probabilities['targetCMean']] + self.logger.info('Last single dec: {}, proba: {:.2f}'.format( + last_single[0], + last_single[1])) + self.logger.info('Last mean dec: {}, proba: {:.2f}'.format( + last_mean[0], + last_mean[1])) + + + if last_mean[1]>self.desision_stop_proba_thr: + self.decision_buffor.append(blink.index) + + # enough of the same decisions condition + one_decision = (len(set(self.decision_buffor)) == 1) + buffor_full = (len(self.decision_buffor) == self.decision_stop) + + self.logger.info("Decision buffor:", self.decision_buffor) + if one_decision and buffor_full: + decision = self.decision_buffor[-1] + self.logger.info('Decision by decision_stop {}'.format(decision)) + self._send_decision(decision) + return + + # number of averaged epochs condition + # ensure all buttons have been averaged self.maximum_to_average number of time + minimum_averaged = min( + len(self.averaged_proba_buffor[i]) for i in self.averaged_proba_buffor.keys() + ) + if minimum_averaged > self.maximum_to_average: + most_confident_decision = max( + self.averaged_proba_buffor.items(), + key = lambda key: key[1][-1] + )[0] + self.logger.info('Decision by max_avr {}'.format(most_confident_decision)) + self._send_decision(most_confident_decision) + return + + + + def create_buffer(self, channel_count, ret_func): + + return AutoBlinkBuffer( + from_blink=int(self.sampling_rate*self.baseline), + samples_count=int((self.window-self.baseline)*self.sampling_rate), + sampling=self.sampling_rate, + num_of_channels=channel_count, + ret_func=ret_func, + ret_format="NUMPY_CHANNELS", + copy_on_ret=0 + ) + + def create_classifier(self): + try: + with open(self.wisdom_path) as clf_file: + classifier = pickle.load(clf_file) + self.logger.info('loaded classifier from wisdom_path') + except Exception as e: + classifier = P300EasyClassifier(targetFs=self.targetFs) + self.logger.info("Loading classifier failed: {}".format(e)) + self.logger.info('Creating new, untrained classifier') + return classifier + def identify_blink(self, blink): + if self.training_index is not None: + if blink.index == self.training_index: + return 'target' + else: + return 'nontarget' + return None + + @log_crash + def init_params(self): + self.logger.info('Initialasing parameters') + #configdence (probability) level for internal decision to be counted to decision stop: + self.desision_stop_proba_thr = float(self.config.get_param( + 'decision_stop_threshold').split(';')[0]) + #available channels + self.channel_names = self.config.get_param( + 'channel_names').split(';') + #used channels + self.channels_for_classification = self.config.get_param( + 'channels_for_classification' + ).split(';') + self.sampling_rate = float( + self.config.get_param('sampling_rate') + ) + #channel montage: + #montage type + self.montage = 'custom' + #montage channels + channels_count = len(self.channel_names) + self.montage_channels = self.config.get_param("montage_channels").strip().split(';') + montage_ids = get_channel_indexes(self.channel_names, self.montage_channels) + self.montage_matrix = get_montage_matrix_custom(channels_count, + montage_ids, + ) + + #pre event baseline in seconds (negative) seconds + self.baseline = float( + self.config.get_param('baseline') + ) + #post event window to consider seconds + self.window = float( + self.config.get_param('window') + ) + + #maximum averaged epochs + #can be inf + self.maximum_to_average = float( + self.config.get_param('maximum_to_average') + ) + #identical decisions to get final answer + self.decision_stop = int(self.config.get_param('decision_stop')) + # downsample to + self.targetFs = float(self.config.get_param('downsample_to')) + # how many virtual "buttons" + # in calibration session logic or something should set + # this parameter to show which field is being used for calibration + try: + self.training_index = int( + self.config.get_param( + 'calibration_field_index') + ) + except ValueError: + self.training_index = None + + self.ignored_blink_ids = [int(i) for i in self.config.get_param('ignored_blink_ids').strip().split(';')] + + self.logger.info('Initialasing buffers') + self._reset_buffors() + self.ready() + + if self.config.get_param('offline_learning') == '1': + self.logger.info('STARTING ONLINE LEARNING') + self.learn_offline() + self.logger.info('DONE LEARNING') + sys.exit(0) + + + @log_crash + def learn_offline(self): + '''Function that reads saved calibration signal, splits it + to epochs and trains classifier''' + self.logger.info("STARTING LEARNING") + + + filter = None + baseline = self.baseline + window = self.window + montage = [self.montage,] + chnls = self.montage_channels + self.logger.info("reference channels {}".format(chnls)) + montage = montage+chnls + #dataset + ds_path = self.config.get_param('offline_learning_dataset_path') + ds_path = os.path.expanduser(ds_path) + + + exclude_channels = exclude = list( + set(self.channel_names + ).difference( + set( + self.channels_for_classification + ) + ) + ) + + ept, epnt = get_epochs_fromfile(ds_path, filter = filter, duration = self.window+1, + montage = montage, + start_offset = baseline, + drop_chnls = exclude_channels + ) + self.logger.info("GOT {} TARGET EPOCHS AND {} NONTARGET".format(len(ept), len(epnt))) + + self.logger.info('EPOCH PARAMS:\n{}'.format(ept[0].get_params())) + evoked_pair_plot_smart_tags(ept, epnt, labels=['target', 'nontarget'], chnames=['O1', 'O2']) + self.wisdom_path = self.wisdom_path = self.config.get_param('wisdom_path') + cl = P300EasyClassifier(targetFs=self.targetFs) + result = cl.calibrate(ept, epnt, bas=baseline, window=window) + + self.logger.info('classifier self score on training set: {}'.format(result)) + with open(self.wisdom_path, 'w') as fname: + pickle.dump(cl, fname) + self.logger.info("classifier -- DONE") + #plot features: + f = np.array(cl.learning_buffor_features) + l = np.array(cl.learning_buffor_classes) + pb.plot(np.median(f[l==0], axis=0)) + pb.plot(np.median(f[l==1], axis=0)) + pb.show() + + + def classify(self, classifier, chunk, blink): + """Compute set of classification probabilities for a given blink. + + May be re-implemented in subclass to perform some pre-processing + or feature extraction on the signal (chunk). + This method will be run by a separate thread. + + Args: + classifier (AbstractClassifier): classifier instance to be used for classification + chunk: numpy 2D data array (channels × samples) + blink: information contained in a single blink + + Returns: + dict. dictionary of {target: probability}, + or None if classification could not be performed + + """ + if time.time()-self.last_dec_timestamp>self.hold_time: + if blink.index in self.ignored_blink_ids: + return None + chunk_ready = self._prepare_chunk(chunk) + self.features[blink.index].append(chunk_ready) + probabilities = {} + probabilities['targetSingle'] = classifier.classify( + chunk_ready + ) + chunk_mean = np.array(self.features[blink.index]).mean(axis=0) + probabilities['targetCMean'] = classifier.classify( + chunk_mean + ) + return probabilities + + def learn(self, classifier, chunk, target): + """Learn that given chunk represents given target. + + May be re-implemented in subclass to perform some pre-processing + or feature extraction on the signal (chunk). + This method will be run by a separate thread. + + Args: + classifier (AbstractClassifier): classifier instance to be used for learning + chunk: numpy 2D data array (channels × samples) + target: name of the target + """ + chunk_ready = self._prepare_chunk(chunk) + classifier.learn(chunk_ready, target) + +if __name__ == '__main__': + P300MasterPeer(settings.MULTIPLEXER_ADDRESSES).loop() diff --git a/obci/interfaces/bci/p300_MD/tests/synthetic_generator.ini b/obci/interfaces/bci/p300_MD/tests/synthetic_generator.ini new file mode 100644 index 00000000..dba2eefe --- /dev/null +++ b/obci/interfaces/bci/p300_MD/tests/synthetic_generator.ini @@ -0,0 +1,23 @@ +[local_params] +channel_names=O1;O2;Pz;Cz +active_channels=0;1;2;3 +channel_gains= +channel_offsets= +sampling_rate=512 +learning=0 +learning_target_field=1 +window=0.5 +blink_duration=0.1 +fields=1;2;3 +isi=0.25 +samples_per_packet=4 +test_trials_n=100 +noise_level=1 +delay=3 +statistics_path=~/synthetic_results +sample_type=FLOAT +synthetic=1 +targets_path= +nontargets_path= +meta_path= + diff --git a/obci/interfaces/bci/p300_MD/tests/synthetic_generator.py b/obci/interfaces/bci/p300_MD/tests/synthetic_generator.py new file mode 100644 index 00000000..e3f1d3df --- /dev/null +++ b/obci/interfaces/bci/p300_MD/tests/synthetic_generator.py @@ -0,0 +1,260 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# +# OpenBCI - framework for Brain-Computer Interfaces based on EEG signal +# Project was initiated by Magdalena Michalska and Krzysztof Kulewski +# as part of their MSc theses at the University of Warsaw. +# Copyright (C) 2008-2009 Krzysztof Kulewski and Magdalena Michalska +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +# +# Author: +# Marian Dovgialo + +from obci.configs import settings +from multiplexer.multiplexer_constants import peers, types +from obci.control.peer.configured_multiplexer_server import ConfiguredMultiplexerServer +from obci.configs import variables_pb2 +from obci.utils.openbci_logging import log_crash +import numpy as np +import time +import random +import sys +from scipy.signal import gaussian +import json +from threading import Thread +from threading import RLock +import pickle + +AMPLITUDE=20 + +class SyntheticGenerator(ConfiguredMultiplexerServer): + '''Peer to send synthetic blinks and signals, and receive + P300 decisions to make some statistics''' + @log_crash + def __init__(self, addresses): + super(SyntheticGenerator, self).__init__(addresses=addresses, + type=peers.LOGIC_FEEDBACK) + + self.lock = RLock() + self.synthetic = int(self.config.get_param('synthetic')) + if self.synthetic==0: + self.targets = np.load(self.config.get_param('targets_path')) + self.nontargets = np.load(self.config.get_param('nontargets_path')) + self.channels_names, self.sampling_rate, self.baseline, channel_gains = self.load_meta() + self.set_param('channel_gains', ';'.join(channel_gains)) + + else: + self.channels_names = self.config.get_param('channel_names').split(';') + self.sampling_rate = float(self.config.get_param('sampling_rate')) + self.set_param('channel_gains', ';'.join( + [str(1.0) for i in self.channels_names])) + self.set_param('channel_offsets', ';'.join( + [str(0.0) for i in self.channels_names])) + + self.learning = int(self.config.get_param('learning')) + self.samples_per_packet = int(self.config.get_param('samples_per_packet')) + self.window = float(self.config.get_param('window')) + self.noise_level = float(self.config.get_param('noise_level')) + self.fields_s = self.config.get_param('fields').split(';') + self.fields = [int(i) for i in self.fields_s] + #inter stimulus interval seconds + self.isi = float(self.config.get_param('isi')) + #selected field + if self.learning: + self.focus = int(self.config.get_param('learning_target_field')) + else: + self.focus = self.fields[0] + #seconds + self.time = time.time() + #timestamp of last blink + self.time_of_blink=0 + self.decisions = [] + self.sent_targets=0 + self.test_trials_n = int(self.config.get_param('test_trials_n')) + self.delay = float(self.config.get_param('delay')) + self.statistics_path = self.config.get_param('statistics_path') + self.command_thread = Thread(target=self.run) + self.command_thread.start() + + + self.logger.info('Init done') + self.ready() + + def load_meta(self): + with open(self.config.get_param('meta_path')) as datafile: + meta = json.load(datafile) + return meta['channels_names'], meta['sampling_rate'], meta['baseline'], meta['channel_gains'] + + + def send_nontarget_blink(self,): + #~ with self.lock: + #~ self.logger.info('sending distractor blink') + choice = random.choice(tuple(set(self.fields)-set([self.focus]))) + b = variables_pb2.Blink() + timestamp = self.time + self.time_of_blink=timestamp + b.timestamp=timestamp + b.index=choice + + self.conn.send_message(message = b.SerializeToString(), + type = types.BLINK_MESSAGE, flush=True) + + def send_target_blink(self, timestamp=None): + b = variables_pb2.Blink() + if not timestamp: + timestamp=self.time + self.time_of_blink=timestamp + b.timestamp=timestamp + b.index=self.focus + + self.conn.send_message(message = b.SerializeToString(), + type = types.BLINK_MESSAGE, flush=True) + + def send_isi(self): + '''send empty signal''' + packets = int((self.isi*self.sampling_rate)/self.samples_per_packet) + length = int(packets*self.samples_per_packet) + if self.synthetic==1: + signal=np.random.normal(scale=self.noise_level, + size=(len(self.channels_names), length)) + else: + selected_nontarget = random.randint(0, self.nontargets.shape[0]-1) + #nontargets are cut to isi + start=int(-self.baseline*self.sampling_rate) + end = start+length + signal = self.nontargets[selected_nontarget, :, start:end] + sleeping_time = self.samples_per_packet*1.0/self.sampling_rate + for p in xrange(packets): + sv = variables_pb2.SampleVector() + for sn in xrange(self.samples_per_packet): + t0 = time.time() + s = sv.samples.add() + ind = p*self.samples_per_packet+sn + s.channels.extend(signal[:, ind].tolist()) + s.timestamp = self.time + self.time+=1.0/self.sampling_rate + + self.conn.send_message(message = sv.SerializeToString(), + type = types.AMPLIFIER_SIGNAL_MESSAGE, flush=True) + if (self.time-self.time_of_blink)>self.isi: + #send blink on "distractor" field + self.send_nontarget_blink() + + left_to_sleep = sleeping_time-(time.time()-t0) + time.sleep(left_to_sleep if left_to_sleep>0 else 0) + + + + def send_target(self): + + #~ with self.lock: + #~ self.logger.info('Sending target, focus: {}'.format(self.focus)) + self.sent_targets+=1 + length_window = int(self.window*self.sampling_rate) + length_packet_aligned = length_window - length_window % self.samples_per_packet + gauss_w = gaussian(length_packet_aligned, length_packet_aligned/10) + chnl_n = len(self.channels_names) + + + if self.synthetic: + signal = np.empty((chnl_n, length_packet_aligned), dtype=float) + for nr in xrange(chnl_n): + #first channel will have biggest amplitude, last smallest + noise = np.random.normal(scale=self.noise_level, + size=length_packet_aligned) + signal[nr] = AMPLITUDE*gauss_w*((chnl_n*1.0-nr)/chnl_n)+noise + self.send_target_blink() + else: + selected_target = random.randint(0, self.targets.shape[0]-1) + signal = self.targets[selected_target] + self.send_target_blink(self.time-self.baseline) + + + sleeping_time = self.samples_per_packet*1.0/self.sampling_rate + for i in xrange(length_packet_aligned/self.samples_per_packet): + t0 = time.time() + sv = variables_pb2.SampleVector() + for sn in xrange(self.samples_per_packet): + s = sv.samples.add() + s.channels.extend(signal[:,i*self.samples_per_packet+sn].tolist()) + s.timestamp = self.time + self.time+=1.0/self.sampling_rate + #~ with self.lock: + self.conn.send_message(message = sv.SerializeToString(), + type = types.AMPLIFIER_SIGNAL_MESSAGE, flush=True) + if (self.time-self.time_of_blink)>self.isi: + self.send_nontarget_blink() + left_to_sleep = sleeping_time-(time.time()-t0) + time.sleep(left_to_sleep if left_to_sleep>0 else 0) + + + @log_crash + def run(self): + #~ with self.lock: + time.sleep(self.delay) + for i in xrange(self.test_trials_n): + for k in xrange(len(self.fields)-1): + #~ with self.lock: + self.send_isi() + #~ with self.lock: + self.send_target() + + self.save_statistics() + sys.exit(0) + + def save_statistics(self): + + self.logger.info('saving statistics') + with open(self.statistics_path, 'w') as f: + json.dump(self.decisions, f) + self.logger.info('saving statistics - done: {}'.format(self.statistics_path)) + N = len(self.decisions) + correct = 0 + targetsN = 0 + for s in self.decisions: + if s['focus'] == s['got_decision']: + correct+=1 + targetsN += s['sent_targets'] + correctperc = 100.0*correct/N + mean_targets = targetsN*1.0/N + self.logger.info( + '''Basic statistics: + correct classifications: {:.2f}\% {} out of {} + mean targets required {:.2f}'''.format(correctperc, correct, N, mean_targets) + ) + + + def handle_message(self, mxmsg): + if mxmsg.type == types.DECISION_MESSAGE: + with self.lock: + self.logger.info('Got message: {}'.format(mxmsg.message)) + + decision = int(mxmsg.message) + self.decisions.append({'sent_targets':self.sent_targets, + 'focus':self.focus, + 'got_decision':decision + } + ) + self.logger.info('got decision: {}'.format(self.decisions[-1])) + self.sent_targets = 0 + if self.learning == 0: + self.focus=random.choice(self.fields) + with self.lock: + self.no_response() + + + +if __name__=='__main__': + SyntheticGenerator(settings.MULTIPLEXER_ADDRESSES).loop() diff --git a/obci/logic/feedback/__init__.py b/obci/logic/feedback/__init__.py new file mode 100644 index 00000000..8d1c8b69 --- /dev/null +++ b/obci/logic/feedback/__init__.py @@ -0,0 +1 @@ + diff --git a/obci/logic/feedback/logic_decision_feedback_budzik_peer.ini b/obci/logic/feedback/logic_decision_feedback_budzik_peer.ini new file mode 100644 index 00000000..3c3231d9 --- /dev/null +++ b/obci/logic/feedback/logic_decision_feedback_budzik_peer.ini @@ -0,0 +1,16 @@ +[local_params] +hello_message= +[launch_dependencies] +analysis= +ugm_server= +ugm_engine= + +[config_sources] +analysis= +ugm_engine= + +[external_params] +blink_ugm_id_start=ugm_engine.blink_ugm_id_start +active_field_ids=ugm_engine.active_field_ids +feed_time=analysis.hold_after_dec +ugm_config=ugm_engine.ugm_config diff --git a/obci/logic/feedback/logic_decision_feedback_budzik_peer.py b/obci/logic/feedback/logic_decision_feedback_budzik_peer.py new file mode 100644 index 00000000..439b4103 --- /dev/null +++ b/obci/logic/feedback/logic_decision_feedback_budzik_peer.py @@ -0,0 +1,88 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# Author: +# Mateusz Kruszyński +# Marian Dovgialo +import time +from multiplexer.multiplexer_constants import peers, types +from obci.control.peer.configured_multiplexer_server import ConfiguredMultiplexerServer + +from obci.gui.ugm import ugm_helper +from obci.configs import settings, variables_pb2 +from obci.utils.openbci_logging import log_crash +from obci.gui.ugm import ugm_config_manager + +class LogicDecisionFeedbackBudzik(ConfiguredMultiplexerServer): + '''Logic to controll N classes BCI + The cartaker should ask a question and then press + space to activate BCI. The BCI user should then concentrate on + answer''' + + @log_crash + def __init__(self, addresses): + #Create a helper object to get configuration from the system + super(LogicDecisionFeedbackBudzik, self).__init__(addresses=addresses, + type=peers.LOGIC_FEEDBACK) + + self.feed_time = float(self.config.get_param('feed_time')) + first_field_id = self.config.get_param('blink_ugm_id_start') + #we need background field id which for id 1001 would be 10001: + first_field_id = int(first_field_id[0] + '0' +first_field_id[1:]) + active_field_offsets = [int(i) for i in self.config.get_param('active_field_ids').split(';')] + ugm_field_ids = [i+first_field_id for i in active_field_offsets] + #~ self.dec_count = int(self.config.get_param('dec_count')) + self.blinking_config = self.config.get_param('ugm_config') + self.blinking_config_ugm = ugm_config_manager.UgmConfigManager(self.blinking_config).config_to_message() + self.feed_manager = ugm_helper.UgmColorUpdater( + self.blinking_config, + ugm_field_ids + ) + + self.HELLO_MESSAGE = self.config.get_param('hello_message') + assert(self.feed_time >= 0) + #~ assert(self.dec_count > 0) + self.ready() + self.begin() + + + def begin(self): + ugm_helper.send_text(self.conn, self.HELLO_MESSAGE) + time.sleep(5) + ugm_helper.send_config(self.conn, self.blinking_config_ugm) + #~ ugm_helper.send_start_blinking(self.conn) + + def handle_message(self, mxmsg): + if mxmsg.type == types.DECISION_MESSAGE: + dec = int(mxmsg.message) + self.logger.info("Got decision: "+str(dec)) + assert(dec >= 0) + dec_time = time.time() + self._send_feedback(dec, dec_time) + elif mxmsg.type == types.UGM_ENGINE_MESSAGE: + msg = variables_pb2.Variable() + msg.ParseFromString(mxmsg.message) + if msg.key == 'keybord_event': + self.logger.info("Got keypress: {}".format(msg.value)) + if msg.value == '32':#space + ugm_helper.send_start_blinking(self.conn) + + self.no_response() + + def _send_feedback(self, dec, dec_time): + ugm_helper.send_stop_blinking(self.conn) + while True: + t = time.time() - dec_time + if t > self.feed_time: + ugm_config = self.feed_manager.update_ugm(dec, -1) + ugm_helper.send_config(self.conn, ugm_config, 1) + break + else: + self.logger.debug("t="+str(t)+"FEED: "+str(t/self.feed_time)) + ugm_config = self.feed_manager.update_ugm(dec, 1-(t/self.feed_time)) + ugm_helper.send_config(self.conn, ugm_config, 1) + time.sleep(0.05) + + +if __name__ == "__main__": + LogicDecisionFeedbackBudzik(settings.MULTIPLEXER_ADDRESSES).loop() + diff --git a/obci/scenarios/budzik/prototypes/P300_haptic_2_class_budzik_amp.ini b/obci/scenarios/budzik/prototypes/P300_haptic_2_class_budzik_amp.ini new file mode 100644 index 00000000..28604353 --- /dev/null +++ b/obci/scenarios/budzik/prototypes/P300_haptic_2_class_budzik_amp.ini @@ -0,0 +1,98 @@ +[peers] +scenario_dir = + +[peers.feedback] +path = logic/feedback/logic_decision_feedback_budzik_peer.py +config = scenarios/budzik/prototypes/P300_haptic_2_class_budzik_configs/feedback.ini + +[peers.feedback.config_sources] +ugm_engine = ugm_engine +analysis = analysis + +[peers.feedback.launch_dependencies] +ugm_server = ugm_server +ugm_engine = ugm_engine +analysis = analysis + +[peers.tag_saver] +path = acquisition/tag_saver_peer.py +config = scenarios/budzik/prototypes/P300_haptic_2_class_budzik_configs/tag_saver.ini + +[peers.tag_saver.config_sources] +signal_saver = signal_saver + +[peers.tag_saver.launch_dependencies] +signal_saver = signal_saver + +[peers.amplifier] +;path=drivers/eeg/amplifier_virtual.py +path = drivers/eeg/cpp_amplifiers/amplifier_tmsi.py +config = scenarios/budzik/prototypes/P300_haptic_2_class_budzik_calibration_configs/amplifier_cap.ini + +[peers.config_server] +path = control/peer/config_server.py +config = scenarios/budzik/prototypes/P300_haptic_2_class_budzik_configs/config_server.ini + +[peers.analysis] +path = interfaces/bci/p300_MD/p300_master_peer.py +config = scenarios/budzik/prototypes/P300_haptic_2_class_budzik_configs/analysis_amp.ini + +[peers.analysis.config_sources] +amplifier = amplifier + +[peers.analysis.launch_dependencies] +amplifier = amplifier + +[peers.ugm_server] +path = gui/ugm/ugm_server_peer.py +config = scenarios/budzik/prototypes/P300_haptic_2_class_budzik_configs/ugm_server.ini + +[peers.ugm_server.config_sources] +ugm_engine = ugm_engine + +[peers.ugm_server.launch_dependencies] +ugm_engine = ugm_engine + +[peers.info_saver] +path = acquisition/info_saver_peer.py +config = scenarios/budzik/prototypes/P300_haptic_2_class_budzik_configs/info_saver.ini + +[peers.info_saver.config_sources] +signal_saver = signal_saver +amplifier = amplifier + +[peers.info_saver.launch_dependencies] +signal_saver = signal_saver +amplifier = amplifier + +[peers.signal_saver] +path = acquisition/signal_saver_peer.py +config = scenarios/budzik/prototypes/P300_haptic_2_class_budzik_configs/signal_saver.ini + +[peers.signal_saver.config_sources] +amplifier = amplifier + +[peers.signal_saver.launch_dependencies] +amplifier = amplifier + +[peers.ugm_engine] +path = gui/ugm/blinking/ugm_modal_blinking_engine_peer.py +config = scenarios/budzik/prototypes/P300_haptic_2_class_budzik_configs/ugm_engine_amp.ini + +[peers.ugm_engine.config_sources] +logic = + +[peers.mx] +path = multiplexer-install/bin/mxcontrol +config = scenarios/budzik/prototypes/P300_haptic_2_class_budzik_configs/mx.ini + +[peers.blink_catcher] +path = utils/blink_catcher_peer.py +config = scenarios/budzik/prototypes/P300_haptic_2_class_budzik_configs/blink_catcher.ini + +[peers.blink_catcher.config_sources] +ugm_engine = ugm_engine + +[peers.blink_catcher.launch_dependencies] +ugm_engine = ugm_engine + diff --git a/obci/scenarios/budzik/prototypes/P300_haptic_2_class_budzik_calibration_amp.ini b/obci/scenarios/budzik/prototypes/P300_haptic_2_class_budzik_calibration_amp.ini new file mode 100644 index 00000000..cb9c10c1 --- /dev/null +++ b/obci/scenarios/budzik/prototypes/P300_haptic_2_class_budzik_calibration_amp.ini @@ -0,0 +1,89 @@ +[peers] +scenario_dir = + +[peers.tag_saver] +path = acquisition/tag_saver_peer.py +config = scenarios/budzik/prototypes/P300_haptic_2_class_budzik_calibration_configs/tag_saver.ini + +[peers.tag_saver.config_sources] +signal_saver = signal_saver + +[peers.tag_saver.launch_dependencies] +signal_saver = signal_saver + +[peers.amplifier] +;path = drivers/eeg/cpp_amplifiers/amplifier_tmsi.py +path=drivers/eeg/amplifier_virtual.py +config = scenarios/budzik/prototypes/P300_haptic_2_class_budzik_calibration_configs/amplifier_cap.ini + +[peers.config_server] +path = control/peer/config_server.py +config = scenarios/budzik/prototypes/P300_haptic_2_class_budzik_calibration_configs/config_server.ini + +[peers.analysis] +path = interfaces/bci/p300_MD/p300_master_peer.py +config = scenarios/budzik/prototypes/P300_haptic_2_class_budzik_calibration_configs/analysis_amp.ini + +[peers.analysis.config_sources] +amplifier = amplifier + +[peers.analysis.launch_dependencies] +amplifier = amplifier + +[peers.ugm_server] +path = gui/ugm/ugm_server_peer.py +config = scenarios/budzik/prototypes/P300_haptic_2_class_budzik_calibration_configs/ugm_server.ini + +[peers.ugm_server.config_sources] +ugm_engine = ugm_engine + +[peers.ugm_server.launch_dependencies] +ugm_engine = ugm_engine + +[peers.info_saver] +path = acquisition/info_saver_peer.py +config = scenarios/budzik/prototypes/P300_haptic_2_class_budzik_calibration_configs/info_saver.ini + +[peers.info_saver.config_sources] +signal_saver = signal_saver +amplifier = amplifier + +[peers.info_saver.launch_dependencies] +signal_saver = signal_saver +amplifier = amplifier + +[peers.logic] +path = interfaces/bci/p300_MD/logic_p300_calibration_peer.py +config = scenarios/budzik/prototypes/P300_haptic_2_class_budzik_calibration_configs/logic.ini + +[peers.logic.config_sources] +ugm_engine = ugm_engine +analysis = analysis + +[peers.logic.launch_dependencies] +signal_saver = signal_saver +ugm_server = ugm_server +ugm_engine = ugm_engine +analysis = analysis + +[peers.signal_saver] +path = acquisition/signal_saver_peer.py +config = scenarios/budzik/prototypes/P300_haptic_2_class_budzik_calibration_configs/signal_saver.ini + +[peers.signal_saver.config_sources] +amplifier = amplifier + +[peers.signal_saver.launch_dependencies] +amplifier = amplifier + +[peers.ugm_engine] +path = gui/ugm/blinking/ugm_modal_blinking_engine_peer.py +config = scenarios/budzik/prototypes/P300_haptic_2_class_budzik_calibration_configs/ugm_engine_amp.ini + +[peers.ugm_engine.config_sources] +logic = + +[peers.mx] +path = multiplexer-install/bin/mxcontrol +config = scenarios/budzik/prototypes/P300_haptic_2_class_budzik_calibration_configs/mx.ini + diff --git a/obci/scenarios/budzik/prototypes/P300_haptic_2_class_budzik_calibration_configs/amplifier.ini b/obci/scenarios/budzik/prototypes/P300_haptic_2_class_budzik_calibration_configs/amplifier.ini new file mode 100644 index 00000000..2fa97c86 --- /dev/null +++ b/obci/scenarios/budzik/prototypes/P300_haptic_2_class_budzik_calibration_configs/amplifier.ini @@ -0,0 +1,17 @@ + +[config_sources] + +[launch_dependencies] + +[external_params] + +[local_params] +active_channels = 0;1;2;3;4;5;6;7;8;Saw;Driver_Saw +channel_names = PO7;O1;Oz;O2;PO8;PO3;PO4;Pz;Cz;AmpSaw;DriverSaw +experiment_uuid = +console_log_level = info +log_dir = ~/.obci/logs +mx_log_level = info +file_log_level = debug +sampling_rate = 512 +sentry_log_level = error diff --git a/obci/scenarios/budzik/prototypes/P300_haptic_2_class_budzik_calibration_configs/amplifier_cap.ini b/obci/scenarios/budzik/prototypes/P300_haptic_2_class_budzik_calibration_configs/amplifier_cap.ini new file mode 100644 index 00000000..8d098d22 --- /dev/null +++ b/obci/scenarios/budzik/prototypes/P300_haptic_2_class_budzik_calibration_configs/amplifier_cap.ini @@ -0,0 +1,17 @@ + +[config_sources] + +[launch_dependencies] + +[external_params] + +[local_params] +channel_names=Fp1;Fpz;Fp2;F7;F3;Fz;F4;F8;M1;T3;C3;Cz;C4;T4;M2;T5;P3;Pz;P4;T6;O1;Oz;O2;l_reka;p_reka;l_noga;eog;haptic1;haptic2;phones +active_channels=0;1;2;3;4;5;6;7;8;9;10;11;12;13;14;15;16;17;18;19;20;21;22;24;25;26;27;28;29;30 +experiment_uuid = +console_log_level = info +log_dir = ~/.obci/logs +mx_log_level = info +file_log_level = debug +sampling_rate = 512 +sentry_log_level = error diff --git a/obci/scenarios/budzik/prototypes/P300_haptic_2_class_budzik_calibration_configs/analysis.ini b/obci/scenarios/budzik/prototypes/P300_haptic_2_class_budzik_calibration_configs/analysis.ini new file mode 100644 index 00000000..7cb4bad7 --- /dev/null +++ b/obci/scenarios/budzik/prototypes/P300_haptic_2_class_budzik_calibration_configs/analysis.ini @@ -0,0 +1,18 @@ + +[config_sources] + +[launch_dependencies] + +[external_params] + +[local_params] +experiment_uuid = +console_log_level = info +channels_for_classification = C3;C4;Pz;Cz +log_dir = ~/.obci/logs +offline_learning = 0 +mx_log_level = info +file_log_level = debug +downsample_to = 24 +sentry_log_level = error +calibration_field_index = 0 diff --git a/obci/scenarios/budzik/prototypes/P300_haptic_2_class_budzik_calibration_configs/analysis_amp.ini b/obci/scenarios/budzik/prototypes/P300_haptic_2_class_budzik_calibration_configs/analysis_amp.ini new file mode 100644 index 00000000..74ecc552 --- /dev/null +++ b/obci/scenarios/budzik/prototypes/P300_haptic_2_class_budzik_calibration_configs/analysis_amp.ini @@ -0,0 +1,19 @@ + +[config_sources] + +[launch_dependencies] + +[external_params] + +[local_params] +experiment_uuid = +console_log_level = info +channels_for_classification = C3;C4;Pz;Cz +montage_channels=M1;M2 +log_dir = ~/.obci/logs +offline_learning = 0 +mx_log_level = info +file_log_level = debug +downsample_to = 24 +sentry_log_level = error +calibration_field_index = 0 diff --git a/obci/scenarios/budzik/prototypes/P300_haptic_2_class_budzik_calibration_configs/blink_catcher.ini b/obci/scenarios/budzik/prototypes/P300_haptic_2_class_budzik_calibration_configs/blink_catcher.ini new file mode 100644 index 00000000..cb6640e0 --- /dev/null +++ b/obci/scenarios/budzik/prototypes/P300_haptic_2_class_budzik_calibration_configs/blink_catcher.ini @@ -0,0 +1,14 @@ + +[config_sources] + +[launch_dependencies] + +[external_params] + +[local_params] +experiment_uuid = +console_log_level = info +log_dir = ~/.obci/logs +mx_log_level = info +file_log_level = debug +sentry_log_level = error diff --git a/obci/scenarios/budzik/prototypes/P300_haptic_2_class_budzik_calibration_configs/config_server.ini b/obci/scenarios/budzik/prototypes/P300_haptic_2_class_budzik_calibration_configs/config_server.ini new file mode 100644 index 00000000..cb6640e0 --- /dev/null +++ b/obci/scenarios/budzik/prototypes/P300_haptic_2_class_budzik_calibration_configs/config_server.ini @@ -0,0 +1,14 @@ + +[config_sources] + +[launch_dependencies] + +[external_params] + +[local_params] +experiment_uuid = +console_log_level = info +log_dir = ~/.obci/logs +mx_log_level = info +file_log_level = debug +sentry_log_level = error diff --git a/obci/scenarios/budzik/prototypes/P300_haptic_2_class_budzik_calibration_configs/feedback.ini b/obci/scenarios/budzik/prototypes/P300_haptic_2_class_budzik_calibration_configs/feedback.ini new file mode 100644 index 00000000..a26604ca --- /dev/null +++ b/obci/scenarios/budzik/prototypes/P300_haptic_2_class_budzik_calibration_configs/feedback.ini @@ -0,0 +1,15 @@ + +[config_sources] + +[launch_dependencies] + +[external_params] + +[local_params] +experiment_uuid = +console_log_level = info +hello_message = Start BCI, wysłuchaj pytania i skup się na odpowiedzi +sentry_log_level = error +mx_log_level = info +file_log_level = debug +log_dir = ~/.obci/logs diff --git a/obci/scenarios/budzik/prototypes/P300_haptic_2_class_budzik_calibration_configs/info_saver.ini b/obci/scenarios/budzik/prototypes/P300_haptic_2_class_budzik_calibration_configs/info_saver.ini new file mode 100644 index 00000000..cb6640e0 --- /dev/null +++ b/obci/scenarios/budzik/prototypes/P300_haptic_2_class_budzik_calibration_configs/info_saver.ini @@ -0,0 +1,14 @@ + +[config_sources] + +[launch_dependencies] + +[external_params] + +[local_params] +experiment_uuid = +console_log_level = info +log_dir = ~/.obci/logs +mx_log_level = info +file_log_level = debug +sentry_log_level = error diff --git a/obci/scenarios/budzik/prototypes/P300_haptic_2_class_budzik_calibration_configs/logic.ini b/obci/scenarios/budzik/prototypes/P300_haptic_2_class_budzik_calibration_configs/logic.ini new file mode 100644 index 00000000..0f502fb6 --- /dev/null +++ b/obci/scenarios/budzik/prototypes/P300_haptic_2_class_budzik_calibration_configs/logic.ini @@ -0,0 +1,17 @@ + +[config_sources] + +[launch_dependencies] +signal_saver = + +[external_params] + +[local_params] +hi_text=Witamy. Zliczaj wibracje po lewej +experiment_uuid = +console_log_level = info +sentry_log_level = error +mx_log_level = info +file_log_level = debug +trials_count = 6 +log_dir = ~/.obci/logs diff --git a/obci/scenarios/budzik/prototypes/P300_haptic_2_class_budzik_calibration_configs/mx.ini b/obci/scenarios/budzik/prototypes/P300_haptic_2_class_budzik_calibration_configs/mx.ini new file mode 100644 index 00000000..cb6640e0 --- /dev/null +++ b/obci/scenarios/budzik/prototypes/P300_haptic_2_class_budzik_calibration_configs/mx.ini @@ -0,0 +1,14 @@ + +[config_sources] + +[launch_dependencies] + +[external_params] + +[local_params] +experiment_uuid = +console_log_level = info +log_dir = ~/.obci/logs +mx_log_level = info +file_log_level = debug +sentry_log_level = error diff --git a/obci/scenarios/budzik/prototypes/P300_haptic_2_class_budzik_calibration_configs/signal_saver.ini b/obci/scenarios/budzik/prototypes/P300_haptic_2_class_budzik_calibration_configs/signal_saver.ini new file mode 100644 index 00000000..cd1348d6 --- /dev/null +++ b/obci/scenarios/budzik/prototypes/P300_haptic_2_class_budzik_calibration_configs/signal_saver.ini @@ -0,0 +1,15 @@ + +[config_sources] + +[launch_dependencies] + +[external_params] + +[local_params] +experiment_uuid = +save_file_name = test2 +console_log_level = info +sentry_log_level = error +mx_log_level = info +file_log_level = debug +log_dir = ~/.obci/logs diff --git a/obci/scenarios/budzik/prototypes/P300_haptic_2_class_budzik_calibration_configs/tag_saver.ini b/obci/scenarios/budzik/prototypes/P300_haptic_2_class_budzik_calibration_configs/tag_saver.ini new file mode 100644 index 00000000..cb6640e0 --- /dev/null +++ b/obci/scenarios/budzik/prototypes/P300_haptic_2_class_budzik_calibration_configs/tag_saver.ini @@ -0,0 +1,14 @@ + +[config_sources] + +[launch_dependencies] + +[external_params] + +[local_params] +experiment_uuid = +console_log_level = info +log_dir = ~/.obci/logs +mx_log_level = info +file_log_level = debug +sentry_log_level = error diff --git a/obci/scenarios/budzik/prototypes/P300_haptic_2_class_budzik_calibration_configs/ugm_engine.ini b/obci/scenarios/budzik/prototypes/P300_haptic_2_class_budzik_calibration_configs/ugm_engine.ini new file mode 100644 index 00000000..33f187ae --- /dev/null +++ b/obci/scenarios/budzik/prototypes/P300_haptic_2_class_budzik_calibration_configs/ugm_engine.ini @@ -0,0 +1,32 @@ + +[config_sources] +logic = + +[launch_dependencies] + +[external_params] + +[local_params] +ugm_config = budzik_visual_p300_2class +blink_ugm_id_start = 1001 +modalities = visual +running_on_start = 0 +haptic_duration = 0.8 +blink_ugm_key = font_color +blink_count_type = random +sentry_log_level = error +blink_ugm_value = #E42525 +log_dir = ~/.obci/logs +blink_count_min = 5 +blink_count_max = 10 +global_target_proba = 0.3 +console_log_level = info +file_log_level = debug +mx_log_level = info +experiment_uuid = +active_field_ids = 0;1 +blink_max_break = 0.22 +blink_min_break = 0.18 +blink_id_count = 2 +blink_ugm_id_count = 2 +blink_ugm_type = singletextimageoddball diff --git a/obci/scenarios/budzik/prototypes/P300_haptic_2_class_budzik_calibration_configs/ugm_engine_amp.ini b/obci/scenarios/budzik/prototypes/P300_haptic_2_class_budzik_calibration_configs/ugm_engine_amp.ini new file mode 100644 index 00000000..fdc26e1f --- /dev/null +++ b/obci/scenarios/budzik/prototypes/P300_haptic_2_class_budzik_calibration_configs/ugm_engine_amp.ini @@ -0,0 +1,34 @@ + +[config_sources] +logic = + +[launch_dependencies] + +[external_params] + +[local_params] +blink_duration=0.15 +target_image_path=obci.gui.ugm.resources.einstein.png +ugm_config = budzik_visual_p300_2class +blink_ugm_id_start = 1001 +modalities = haptic +running_on_start = 0 +haptic_duration = 0.15 +blink_ugm_key = font_color +blink_count_type = random +sentry_log_level = error +blink_ugm_value = #E42525 +log_dir = ~/.obci/logs +blink_count_min = 10 +blink_count_max = 15 +global_target_proba = 1 +console_log_level = info +file_log_level = debug +mx_log_level = info +experiment_uuid = +active_field_ids = 0;1 +blink_max_break = 0.22 +blink_min_break = 0.18 +blink_id_count = 2 +blink_ugm_id_count = 2 +blink_ugm_type = singletextimageoddball diff --git a/obci/scenarios/budzik/prototypes/P300_haptic_2_class_budzik_calibration_configs/ugm_server.ini b/obci/scenarios/budzik/prototypes/P300_haptic_2_class_budzik_calibration_configs/ugm_server.ini new file mode 100644 index 00000000..cb6640e0 --- /dev/null +++ b/obci/scenarios/budzik/prototypes/P300_haptic_2_class_budzik_calibration_configs/ugm_server.ini @@ -0,0 +1,14 @@ + +[config_sources] + +[launch_dependencies] + +[external_params] + +[local_params] +experiment_uuid = +console_log_level = info +log_dir = ~/.obci/logs +mx_log_level = info +file_log_level = debug +sentry_log_level = error diff --git a/obci/scenarios/budzik/prototypes/P300_haptic_2_class_budzik_configs/amplifier.ini b/obci/scenarios/budzik/prototypes/P300_haptic_2_class_budzik_configs/amplifier.ini new file mode 100644 index 00000000..2fa97c86 --- /dev/null +++ b/obci/scenarios/budzik/prototypes/P300_haptic_2_class_budzik_configs/amplifier.ini @@ -0,0 +1,17 @@ + +[config_sources] + +[launch_dependencies] + +[external_params] + +[local_params] +active_channels = 0;1;2;3;4;5;6;7;8;Saw;Driver_Saw +channel_names = PO7;O1;Oz;O2;PO8;PO3;PO4;Pz;Cz;AmpSaw;DriverSaw +experiment_uuid = +console_log_level = info +log_dir = ~/.obci/logs +mx_log_level = info +file_log_level = debug +sampling_rate = 512 +sentry_log_level = error diff --git a/obci/scenarios/budzik/prototypes/P300_haptic_2_class_budzik_configs/analysis.ini b/obci/scenarios/budzik/prototypes/P300_haptic_2_class_budzik_configs/analysis.ini new file mode 100644 index 00000000..9489a15b --- /dev/null +++ b/obci/scenarios/budzik/prototypes/P300_haptic_2_class_budzik_configs/analysis.ini @@ -0,0 +1,17 @@ + +[config_sources] + +[launch_dependencies] + +[external_params] + +[local_params] +experiment_uuid = +console_log_level = info +channels_for_classification = O1;O2;Pz;Cz +log_dir = ~/.obci/logs +offline_learning = 0 +mx_log_level = info +file_log_level = debug +downsample_to = 24 +sentry_log_level = error diff --git a/obci/scenarios/budzik/prototypes/P300_haptic_2_class_budzik_configs/analysis_amp.ini b/obci/scenarios/budzik/prototypes/P300_haptic_2_class_budzik_configs/analysis_amp.ini new file mode 100644 index 00000000..1ae308ea --- /dev/null +++ b/obci/scenarios/budzik/prototypes/P300_haptic_2_class_budzik_configs/analysis_amp.ini @@ -0,0 +1,19 @@ + +[config_sources] + +[launch_dependencies] + +[external_params] + +[local_params] +experiment_uuid = +console_log_level = info +channels_for_classification = C3;C4;Pz;Cz +montage_channels=M1;M2 +log_dir = ~/.obci/logs +offline_learning = 0 +mx_log_level = info +file_log_level = debug +downsample_to = 24 +sentry_log_level = error +calibration_field_index = diff --git a/obci/scenarios/budzik/prototypes/P300_haptic_2_class_budzik_configs/blink_catcher.ini b/obci/scenarios/budzik/prototypes/P300_haptic_2_class_budzik_configs/blink_catcher.ini new file mode 100644 index 00000000..cb6640e0 --- /dev/null +++ b/obci/scenarios/budzik/prototypes/P300_haptic_2_class_budzik_configs/blink_catcher.ini @@ -0,0 +1,14 @@ + +[config_sources] + +[launch_dependencies] + +[external_params] + +[local_params] +experiment_uuid = +console_log_level = info +log_dir = ~/.obci/logs +mx_log_level = info +file_log_level = debug +sentry_log_level = error diff --git a/obci/scenarios/budzik/prototypes/P300_haptic_2_class_budzik_configs/config_server.ini b/obci/scenarios/budzik/prototypes/P300_haptic_2_class_budzik_configs/config_server.ini new file mode 100644 index 00000000..cb6640e0 --- /dev/null +++ b/obci/scenarios/budzik/prototypes/P300_haptic_2_class_budzik_configs/config_server.ini @@ -0,0 +1,14 @@ + +[config_sources] + +[launch_dependencies] + +[external_params] + +[local_params] +experiment_uuid = +console_log_level = info +log_dir = ~/.obci/logs +mx_log_level = info +file_log_level = debug +sentry_log_level = error diff --git a/obci/scenarios/budzik/prototypes/P300_haptic_2_class_budzik_configs/feedback.ini b/obci/scenarios/budzik/prototypes/P300_haptic_2_class_budzik_configs/feedback.ini new file mode 100644 index 00000000..35142b5d --- /dev/null +++ b/obci/scenarios/budzik/prototypes/P300_haptic_2_class_budzik_configs/feedback.ini @@ -0,0 +1,15 @@ + +[config_sources] + +[launch_dependencies] + +[external_params] + +[local_params] +hello_message=Start BCI, wysłuchaj pytania i skup się na odpowiedzi lewo - TAK, prawo - NIE +experiment_uuid = +console_log_level = info +log_dir = ~/.obci/logs +mx_log_level = info +file_log_level = debug +sentry_log_level = error diff --git a/obci/scenarios/budzik/prototypes/P300_haptic_2_class_budzik_configs/info_saver.ini b/obci/scenarios/budzik/prototypes/P300_haptic_2_class_budzik_configs/info_saver.ini new file mode 100644 index 00000000..cb6640e0 --- /dev/null +++ b/obci/scenarios/budzik/prototypes/P300_haptic_2_class_budzik_configs/info_saver.ini @@ -0,0 +1,14 @@ + +[config_sources] + +[launch_dependencies] + +[external_params] + +[local_params] +experiment_uuid = +console_log_level = info +log_dir = ~/.obci/logs +mx_log_level = info +file_log_level = debug +sentry_log_level = error diff --git a/obci/scenarios/budzik/prototypes/P300_haptic_2_class_budzik_configs/logic.ini b/obci/scenarios/budzik/prototypes/P300_haptic_2_class_budzik_configs/logic.ini new file mode 100644 index 00000000..02bf4bc9 --- /dev/null +++ b/obci/scenarios/budzik/prototypes/P300_haptic_2_class_budzik_configs/logic.ini @@ -0,0 +1,19 @@ + +[config_sources] + +[launch_dependencies] +signal_saver = + +[external_params] + +[local_params] +experiment_uuid = +active_field_ids = 0;2;5 +dec_count = 3 +logic_decision_config = obci.logic.configs.config_maze_rovio.Config +robot_ip = 192.168.1.18 +console_log_level = info +sentry_log_level = error +mx_log_level = info +file_log_level = debug +log_dir = ~/.obci/logs diff --git a/obci/scenarios/budzik/prototypes/P300_haptic_2_class_budzik_configs/mx.ini b/obci/scenarios/budzik/prototypes/P300_haptic_2_class_budzik_configs/mx.ini new file mode 100644 index 00000000..cb6640e0 --- /dev/null +++ b/obci/scenarios/budzik/prototypes/P300_haptic_2_class_budzik_configs/mx.ini @@ -0,0 +1,14 @@ + +[config_sources] + +[launch_dependencies] + +[external_params] + +[local_params] +experiment_uuid = +console_log_level = info +log_dir = ~/.obci/logs +mx_log_level = info +file_log_level = debug +sentry_log_level = error diff --git a/obci/scenarios/budzik/prototypes/P300_haptic_2_class_budzik_configs/signal_saver.ini b/obci/scenarios/budzik/prototypes/P300_haptic_2_class_budzik_configs/signal_saver.ini new file mode 100644 index 00000000..cd1348d6 --- /dev/null +++ b/obci/scenarios/budzik/prototypes/P300_haptic_2_class_budzik_configs/signal_saver.ini @@ -0,0 +1,15 @@ + +[config_sources] + +[launch_dependencies] + +[external_params] + +[local_params] +experiment_uuid = +save_file_name = test2 +console_log_level = info +sentry_log_level = error +mx_log_level = info +file_log_level = debug +log_dir = ~/.obci/logs diff --git a/obci/scenarios/budzik/prototypes/P300_haptic_2_class_budzik_configs/switch.ini b/obci/scenarios/budzik/prototypes/P300_haptic_2_class_budzik_configs/switch.ini new file mode 100644 index 00000000..cb6640e0 --- /dev/null +++ b/obci/scenarios/budzik/prototypes/P300_haptic_2_class_budzik_configs/switch.ini @@ -0,0 +1,14 @@ + +[config_sources] + +[launch_dependencies] + +[external_params] + +[local_params] +experiment_uuid = +console_log_level = info +log_dir = ~/.obci/logs +mx_log_level = info +file_log_level = debug +sentry_log_level = error diff --git a/obci/scenarios/budzik/prototypes/P300_haptic_2_class_budzik_configs/switch_backup.ini b/obci/scenarios/budzik/prototypes/P300_haptic_2_class_budzik_configs/switch_backup.ini new file mode 100644 index 00000000..81e49483 --- /dev/null +++ b/obci/scenarios/budzik/prototypes/P300_haptic_2_class_budzik_configs/switch_backup.ini @@ -0,0 +1,15 @@ + +[config_sources] + +[launch_dependencies] + +[external_params] + +[local_params] +experiment_uuid = +console_log_level = info +log_dir = ~/.obci/logs +sentry_log_level = error +mx_log_level = info +file_log_level = debug +finish_saving = 1 diff --git a/obci/scenarios/budzik/prototypes/P300_haptic_2_class_budzik_configs/tag_saver.ini b/obci/scenarios/budzik/prototypes/P300_haptic_2_class_budzik_configs/tag_saver.ini new file mode 100644 index 00000000..cb6640e0 --- /dev/null +++ b/obci/scenarios/budzik/prototypes/P300_haptic_2_class_budzik_configs/tag_saver.ini @@ -0,0 +1,14 @@ + +[config_sources] + +[launch_dependencies] + +[external_params] + +[local_params] +experiment_uuid = +console_log_level = info +log_dir = ~/.obci/logs +mx_log_level = info +file_log_level = debug +sentry_log_level = error diff --git a/obci/scenarios/budzik/prototypes/P300_haptic_2_class_budzik_configs/ugm_engine.ini b/obci/scenarios/budzik/prototypes/P300_haptic_2_class_budzik_configs/ugm_engine.ini new file mode 100644 index 00000000..47bb60fc --- /dev/null +++ b/obci/scenarios/budzik/prototypes/P300_haptic_2_class_budzik_configs/ugm_engine.ini @@ -0,0 +1,31 @@ + +[config_sources] +logic = + +[launch_dependencies] + +[external_params] + +[local_params] +ugm_config = budzik_visual_p300_2class +blink_ugm_id_start = 1001 +modalities = visual +running_on_start = 0 +haptic_duration = 0.8 +blink_ugm_key = font_color +sentry_log_level = error +blink_ugm_value = #E42525 +log_dir = ~/.obci/logs +blink_count_min = 64 +blink_count_max = 80 +global_target_proba = 0.3 +console_log_level = info +file_log_level = debug +mx_log_level = info +experiment_uuid = +active_field_ids = 0;1 +blink_max_break = 0.22 +blink_min_break = 0.18 +blink_id_count = 2 +blink_ugm_id_count = 2 +blink_ugm_type = singletextimageoddball diff --git a/obci/scenarios/budzik/prototypes/P300_haptic_2_class_budzik_configs/ugm_engine_amp.ini b/obci/scenarios/budzik/prototypes/P300_haptic_2_class_budzik_configs/ugm_engine_amp.ini new file mode 100644 index 00000000..6dcfb346 --- /dev/null +++ b/obci/scenarios/budzik/prototypes/P300_haptic_2_class_budzik_configs/ugm_engine_amp.ini @@ -0,0 +1,33 @@ + +[config_sources] +logic = + +[launch_dependencies] + +[external_params] + +[local_params] +blink_duration=0.15 +target_image_path=obci.gui.ugm.resources.einstein.png +ugm_config = budzik_visual_p300_2class +blink_ugm_id_start = 1001 +modalities = haptic +running_on_start = 0 +haptic_duration = 0.15 +blink_ugm_key = font_color +sentry_log_level = error +blink_ugm_value = #E42525 +log_dir = ~/.obci/logs +blink_count_min = 64 +blink_count_max = 80 +global_target_proba = 1 +console_log_level = info +file_log_level = debug +mx_log_level = info +experiment_uuid = +active_field_ids = 0;1 +blink_max_break = 0.22 +blink_min_break = 0.18 +blink_id_count = 2 +blink_ugm_id_count = 2 +blink_ugm_type = singletextimageoddball diff --git a/obci/scenarios/budzik/prototypes/P300_haptic_2_class_budzik_configs/ugm_server.ini b/obci/scenarios/budzik/prototypes/P300_haptic_2_class_budzik_configs/ugm_server.ini new file mode 100644 index 00000000..cb6640e0 --- /dev/null +++ b/obci/scenarios/budzik/prototypes/P300_haptic_2_class_budzik_configs/ugm_server.ini @@ -0,0 +1,14 @@ + +[config_sources] + +[launch_dependencies] + +[external_params] + +[local_params] +experiment_uuid = +console_log_level = info +log_dir = ~/.obci/logs +mx_log_level = info +file_log_level = debug +sentry_log_level = error diff --git a/obci/scenarios/budzik/prototypes/P300_visual_2_class_budzik.ini b/obci/scenarios/budzik/prototypes/P300_visual_2_class_budzik.ini new file mode 100644 index 00000000..35d4b755 --- /dev/null +++ b/obci/scenarios/budzik/prototypes/P300_visual_2_class_budzik.ini @@ -0,0 +1,97 @@ +[peers] +scenario_dir = + +[peers.feedback] +path = logic/feedback/logic_decision_feedback_budzik_peer.py +config = scenarios/budzik/prototypes/P300_visual_2_class_budzik_configs/feedback.ini + +[peers.feedback.config_sources] +ugm_engine = ugm_engine +analysis = analysis + +[peers.feedback.launch_dependencies] +ugm_server = ugm_server +ugm_engine = ugm_engine +analysis = analysis + +[peers.tag_saver] +path = acquisition/tag_saver_peer.py +config = scenarios/budzik/prototypes/P300_visual_2_class_budzik_configs/tag_saver.ini + +[peers.tag_saver.config_sources] +signal_saver = signal_saver + +[peers.tag_saver.launch_dependencies] +signal_saver = signal_saver + +[peers.amplifier] +path = drivers/eeg/amplifier_virtual.py +config = scenarios/budzik/prototypes/P300_visual_2_class_budzik_configs/amplifier.ini + +[peers.config_server] +path = control/peer/config_server.py +config = scenarios/budzik/prototypes/P300_visual_2_class_budzik_configs/config_server.ini + +[peers.analysis] +path = interfaces/bci/p300_MD/p300_master_peer.py +config = scenarios/budzik/prototypes/P300_visual_2_class_budzik_configs/analysis.ini + +[peers.analysis.config_sources] +amplifier = amplifier + +[peers.analysis.launch_dependencies] +amplifier = amplifier + +[peers.ugm_server] +path = gui/ugm/ugm_server_peer.py +config = scenarios/budzik/prototypes/P300_visual_2_class_budzik_configs/ugm_server.ini + +[peers.ugm_server.config_sources] +ugm_engine = ugm_engine + +[peers.ugm_server.launch_dependencies] +ugm_engine = ugm_engine + +[peers.info_saver] +path = acquisition/info_saver_peer.py +config = scenarios/budzik/prototypes/P300_visual_2_class_budzik_configs/info_saver.ini + +[peers.info_saver.config_sources] +signal_saver = signal_saver +amplifier = amplifier + +[peers.info_saver.launch_dependencies] +signal_saver = signal_saver +amplifier = amplifier + +[peers.signal_saver] +path = acquisition/signal_saver_peer.py +config = scenarios/budzik/prototypes/P300_visual_2_class_budzik_configs/signal_saver.ini + +[peers.signal_saver.config_sources] +amplifier = amplifier + +[peers.signal_saver.launch_dependencies] +amplifier = amplifier + +[peers.ugm_engine] +path = gui/ugm/blinking/ugm_modal_blinking_engine_peer.py +config = scenarios/budzik/prototypes/P300_visual_2_class_budzik_configs/ugm_engine.ini + +[peers.ugm_engine.config_sources] +logic = + +[peers.mx] +path = multiplexer-install/bin/mxcontrol +config = scenarios/budzik/prototypes/P300_visual_2_class_budzik_configs/mx.ini + +[peers.blink_catcher] +path = utils/blink_catcher_peer.py +config = scenarios/budzik/prototypes/P300_visual_2_class_budzik_configs/blink_catcher.ini + +[peers.blink_catcher.config_sources] +ugm_engine = ugm_engine + +[peers.blink_catcher.launch_dependencies] +ugm_engine = ugm_engine + diff --git a/obci/scenarios/budzik/prototypes/P300_visual_2_class_budzik_amp.ini b/obci/scenarios/budzik/prototypes/P300_visual_2_class_budzik_amp.ini new file mode 100644 index 00000000..45835934 --- /dev/null +++ b/obci/scenarios/budzik/prototypes/P300_visual_2_class_budzik_amp.ini @@ -0,0 +1,98 @@ +[peers] +scenario_dir = + +[peers.feedback] +path = logic/feedback/logic_decision_feedback_budzik_peer.py +config = scenarios/budzik/prototypes/P300_visual_2_class_budzik_configs/feedback.ini + +[peers.feedback.config_sources] +ugm_engine = ugm_engine +analysis = analysis + +[peers.feedback.launch_dependencies] +ugm_server = ugm_server +ugm_engine = ugm_engine +analysis = analysis + +[peers.tag_saver] +path = acquisition/tag_saver_peer.py +config = scenarios/budzik/prototypes/P300_visual_2_class_budzik_configs/tag_saver.ini + +[peers.tag_saver.config_sources] +signal_saver = signal_saver + +[peers.tag_saver.launch_dependencies] +signal_saver = signal_saver + +[peers.amplifier] +;path=drivers/eeg/amplifier_virtual.py +path = drivers/eeg/cpp_amplifiers/amplifier_tmsi.py +config = scenarios/budzik/prototypes/P300_visual_2_class_budzik_calibration_configs/amplifier_cap.ini + +[peers.config_server] +path = control/peer/config_server.py +config = scenarios/budzik/prototypes/P300_visual_2_class_budzik_configs/config_server.ini + +[peers.analysis] +path = interfaces/bci/p300_MD/p300_master_peer.py +config = scenarios/budzik/prototypes/P300_visual_2_class_budzik_configs/analysis_amp.ini + +[peers.analysis.config_sources] +amplifier = amplifier + +[peers.analysis.launch_dependencies] +amplifier = amplifier + +[peers.ugm_server] +path = gui/ugm/ugm_server_peer.py +config = scenarios/budzik/prototypes/P300_visual_2_class_budzik_configs/ugm_server.ini + +[peers.ugm_server.config_sources] +ugm_engine = ugm_engine + +[peers.ugm_server.launch_dependencies] +ugm_engine = ugm_engine + +[peers.info_saver] +path = acquisition/info_saver_peer.py +config = scenarios/budzik/prototypes/P300_visual_2_class_budzik_configs/info_saver.ini + +[peers.info_saver.config_sources] +signal_saver = signal_saver +amplifier = amplifier + +[peers.info_saver.launch_dependencies] +signal_saver = signal_saver +amplifier = amplifier + +[peers.signal_saver] +path = acquisition/signal_saver_peer.py +config = scenarios/budzik/prototypes/P300_visual_2_class_budzik_configs/signal_saver.ini + +[peers.signal_saver.config_sources] +amplifier = amplifier + +[peers.signal_saver.launch_dependencies] +amplifier = amplifier + +[peers.ugm_engine] +path = gui/ugm/blinking/ugm_modal_blinking_engine_peer.py +config = scenarios/budzik/prototypes/P300_visual_2_class_budzik_configs/ugm_engine_amp.ini + +[peers.ugm_engine.config_sources] +logic = + +[peers.mx] +path = multiplexer-install/bin/mxcontrol +config = scenarios/budzik/prototypes/P300_visual_2_class_budzik_configs/mx.ini + +;[peers.blink_catcher] +;path = utils/blink_catcher_peer.py +;config = scenarios/budzik/prototypes/P300_visual_2_class_budzik_configs/blink_catcher.ini + +;[peers.blink_catcher.config_sources] +;ugm_engine = ugm_engine + +;[peers.blink_catcher.launch_dependencies] +;ugm_engine = ugm_engine + diff --git a/obci/scenarios/budzik/prototypes/P300_visual_2_class_budzik_calibration.ini b/obci/scenarios/budzik/prototypes/P300_visual_2_class_budzik_calibration.ini new file mode 100644 index 00000000..d9a9a8a0 --- /dev/null +++ b/obci/scenarios/budzik/prototypes/P300_visual_2_class_budzik_calibration.ini @@ -0,0 +1,88 @@ +[peers] +scenario_dir = + +[peers.tag_saver] +path = acquisition/tag_saver_peer.py +config = scenarios/budzik/prototypes/P300_visual_2_class_budzik_calibration_configs/tag_saver.ini + +[peers.tag_saver.config_sources] +signal_saver = signal_saver + +[peers.tag_saver.launch_dependencies] +signal_saver = signal_saver + +[peers.amplifier] +path = drivers/eeg/amplifier_virtual.py +config = scenarios/budzik/prototypes/P300_visual_2_class_budzik_calibration_configs/amplifier.ini + +[peers.config_server] +path = control/peer/config_server.py +config = scenarios/budzik/prototypes/P300_visual_2_class_budzik_calibration_configs/config_server.ini + +[peers.analysis] +path = interfaces/bci/p300_MD/p300_master_peer.py +config = scenarios/budzik/prototypes/P300_visual_2_class_budzik_calibration_configs/analysis.ini + +[peers.analysis.config_sources] +amplifier = amplifier + +[peers.analysis.launch_dependencies] +amplifier = amplifier + +[peers.ugm_server] +path = gui/ugm/ugm_server_peer.py +config = scenarios/budzik/prototypes/P300_visual_2_class_budzik_calibration_configs/ugm_server.ini + +[peers.ugm_server.config_sources] +ugm_engine = ugm_engine + +[peers.ugm_server.launch_dependencies] +ugm_engine = ugm_engine + +[peers.info_saver] +path = acquisition/info_saver_peer.py +config = scenarios/budzik/prototypes/P300_visual_2_class_budzik_calibration_configs/info_saver.ini + +[peers.info_saver.config_sources] +signal_saver = signal_saver +amplifier = amplifier + +[peers.info_saver.launch_dependencies] +signal_saver = signal_saver +amplifier = amplifier + +[peers.logic] +path = interfaces/bci/p300_MD/logic_p300_calibration_peer.py +config = scenarios/budzik/prototypes/P300_visual_2_class_budzik_calibration_configs/logic.ini + +[peers.logic.config_sources] +ugm_engine = ugm_engine +analysis = analysis + +[peers.logic.launch_dependencies] +signal_saver = signal_saver +ugm_server = ugm_server +ugm_engine = ugm_engine +analysis = analysis + +[peers.signal_saver] +path = acquisition/signal_saver_peer.py +config = scenarios/budzik/prototypes/P300_visual_2_class_budzik_calibration_configs/signal_saver.ini + +[peers.signal_saver.config_sources] +amplifier = amplifier + +[peers.signal_saver.launch_dependencies] +amplifier = amplifier + +[peers.ugm_engine] +path = gui/ugm/blinking/ugm_modal_blinking_engine_peer.py +config = scenarios/budzik/prototypes/P300_visual_2_class_budzik_calibration_configs/ugm_engine.ini + +[peers.ugm_engine.config_sources] +logic = + +[peers.mx] +path = multiplexer-install/bin/mxcontrol +config = scenarios/budzik/prototypes/P300_visual_2_class_budzik_calibration_configs/mx.ini + diff --git a/obci/scenarios/budzik/prototypes/P300_visual_2_class_budzik_calibration_amp.ini b/obci/scenarios/budzik/prototypes/P300_visual_2_class_budzik_calibration_amp.ini new file mode 100644 index 00000000..17e58582 --- /dev/null +++ b/obci/scenarios/budzik/prototypes/P300_visual_2_class_budzik_calibration_amp.ini @@ -0,0 +1,89 @@ +[peers] +scenario_dir = + +[peers.tag_saver] +path = acquisition/tag_saver_peer.py +config = scenarios/budzik/prototypes/P300_visual_2_class_budzik_calibration_configs/tag_saver.ini + +[peers.tag_saver.config_sources] +signal_saver = signal_saver + +[peers.tag_saver.launch_dependencies] +signal_saver = signal_saver + +[peers.amplifier] +path = drivers/eeg/cpp_amplifiers/amplifier_tmsi.py +;path=drivers/eeg/amplifier_virtual.py +config = scenarios/budzik/prototypes/P300_visual_2_class_budzik_calibration_configs/amplifier_cap.ini + +[peers.config_server] +path = control/peer/config_server.py +config = scenarios/budzik/prototypes/P300_visual_2_class_budzik_calibration_configs/config_server.ini + +[peers.analysis] +path = interfaces/bci/p300_MD/p300_master_peer.py +config = scenarios/budzik/prototypes/P300_visual_2_class_budzik_calibration_configs/analysis_amp.ini + +[peers.analysis.config_sources] +amplifier = amplifier + +[peers.analysis.launch_dependencies] +amplifier = amplifier + +[peers.ugm_server] +path = gui/ugm/ugm_server_peer.py +config = scenarios/budzik/prototypes/P300_visual_2_class_budzik_calibration_configs/ugm_server.ini + +[peers.ugm_server.config_sources] +ugm_engine = ugm_engine + +[peers.ugm_server.launch_dependencies] +ugm_engine = ugm_engine + +[peers.info_saver] +path = acquisition/info_saver_peer.py +config = scenarios/budzik/prototypes/P300_visual_2_class_budzik_calibration_configs/info_saver.ini + +[peers.info_saver.config_sources] +signal_saver = signal_saver +amplifier = amplifier + +[peers.info_saver.launch_dependencies] +signal_saver = signal_saver +amplifier = amplifier + +[peers.logic] +path = interfaces/bci/p300_MD/logic_p300_calibration_peer.py +config = scenarios/budzik/prototypes/P300_visual_2_class_budzik_calibration_configs/logic.ini + +[peers.logic.config_sources] +ugm_engine = ugm_engine +analysis = analysis + +[peers.logic.launch_dependencies] +signal_saver = signal_saver +ugm_server = ugm_server +ugm_engine = ugm_engine +analysis = analysis + +[peers.signal_saver] +path = acquisition/signal_saver_peer.py +config = scenarios/budzik/prototypes/P300_visual_2_class_budzik_calibration_configs/signal_saver.ini + +[peers.signal_saver.config_sources] +amplifier = amplifier + +[peers.signal_saver.launch_dependencies] +amplifier = amplifier + +[peers.ugm_engine] +path = gui/ugm/blinking/ugm_modal_blinking_engine_peer.py +config = scenarios/budzik/prototypes/P300_visual_2_class_budzik_calibration_configs/ugm_engine_amp.ini + +[peers.ugm_engine.config_sources] +logic = + +[peers.mx] +path = multiplexer-install/bin/mxcontrol +config = scenarios/budzik/prototypes/P300_visual_2_class_budzik_calibration_configs/mx.ini + diff --git a/obci/scenarios/budzik/prototypes/P300_visual_2_class_budzik_calibration_configs/amplifier.ini b/obci/scenarios/budzik/prototypes/P300_visual_2_class_budzik_calibration_configs/amplifier.ini new file mode 100644 index 00000000..2fa97c86 --- /dev/null +++ b/obci/scenarios/budzik/prototypes/P300_visual_2_class_budzik_calibration_configs/amplifier.ini @@ -0,0 +1,17 @@ + +[config_sources] + +[launch_dependencies] + +[external_params] + +[local_params] +active_channels = 0;1;2;3;4;5;6;7;8;Saw;Driver_Saw +channel_names = PO7;O1;Oz;O2;PO8;PO3;PO4;Pz;Cz;AmpSaw;DriverSaw +experiment_uuid = +console_log_level = info +log_dir = ~/.obci/logs +mx_log_level = info +file_log_level = debug +sampling_rate = 512 +sentry_log_level = error diff --git a/obci/scenarios/budzik/prototypes/P300_visual_2_class_budzik_calibration_configs/amplifier_cap.ini b/obci/scenarios/budzik/prototypes/P300_visual_2_class_budzik_calibration_configs/amplifier_cap.ini new file mode 100644 index 00000000..8d098d22 --- /dev/null +++ b/obci/scenarios/budzik/prototypes/P300_visual_2_class_budzik_calibration_configs/amplifier_cap.ini @@ -0,0 +1,17 @@ + +[config_sources] + +[launch_dependencies] + +[external_params] + +[local_params] +channel_names=Fp1;Fpz;Fp2;F7;F3;Fz;F4;F8;M1;T3;C3;Cz;C4;T4;M2;T5;P3;Pz;P4;T6;O1;Oz;O2;l_reka;p_reka;l_noga;eog;haptic1;haptic2;phones +active_channels=0;1;2;3;4;5;6;7;8;9;10;11;12;13;14;15;16;17;18;19;20;21;22;24;25;26;27;28;29;30 +experiment_uuid = +console_log_level = info +log_dir = ~/.obci/logs +mx_log_level = info +file_log_level = debug +sampling_rate = 512 +sentry_log_level = error diff --git a/obci/scenarios/budzik/prototypes/P300_visual_2_class_budzik_calibration_configs/analysis.ini b/obci/scenarios/budzik/prototypes/P300_visual_2_class_budzik_calibration_configs/analysis.ini new file mode 100644 index 00000000..422b3c15 --- /dev/null +++ b/obci/scenarios/budzik/prototypes/P300_visual_2_class_budzik_calibration_configs/analysis.ini @@ -0,0 +1,18 @@ + +[config_sources] + +[launch_dependencies] + +[external_params] + +[local_params] +experiment_uuid = +console_log_level = info +channels_for_classification = O1;O2;Pz;Cz +log_dir = ~/.obci/logs +offline_learning = 0 +mx_log_level = info +file_log_level = debug +downsample_to = 24 +sentry_log_level = error +calibration_field_index = 0 diff --git a/obci/scenarios/budzik/prototypes/P300_visual_2_class_budzik_calibration_configs/analysis_amp.ini b/obci/scenarios/budzik/prototypes/P300_visual_2_class_budzik_calibration_configs/analysis_amp.ini new file mode 100644 index 00000000..2cd0a21e --- /dev/null +++ b/obci/scenarios/budzik/prototypes/P300_visual_2_class_budzik_calibration_configs/analysis_amp.ini @@ -0,0 +1,19 @@ + +[config_sources] + +[launch_dependencies] + +[external_params] + +[local_params] +experiment_uuid = +console_log_level = info +channels_for_classification = O1;O2;Pz;Cz;M1;M2 +montage_channels=M1;M2 +log_dir = ~/.obci/logs +offline_learning = 0 +mx_log_level = info +file_log_level = debug +downsample_to = 24 +sentry_log_level = error +calibration_field_index = 0 diff --git a/obci/scenarios/budzik/prototypes/P300_visual_2_class_budzik_calibration_configs/blink_catcher.ini b/obci/scenarios/budzik/prototypes/P300_visual_2_class_budzik_calibration_configs/blink_catcher.ini new file mode 100644 index 00000000..cb6640e0 --- /dev/null +++ b/obci/scenarios/budzik/prototypes/P300_visual_2_class_budzik_calibration_configs/blink_catcher.ini @@ -0,0 +1,14 @@ + +[config_sources] + +[launch_dependencies] + +[external_params] + +[local_params] +experiment_uuid = +console_log_level = info +log_dir = ~/.obci/logs +mx_log_level = info +file_log_level = debug +sentry_log_level = error diff --git a/obci/scenarios/budzik/prototypes/P300_visual_2_class_budzik_calibration_configs/config_server.ini b/obci/scenarios/budzik/prototypes/P300_visual_2_class_budzik_calibration_configs/config_server.ini new file mode 100644 index 00000000..cb6640e0 --- /dev/null +++ b/obci/scenarios/budzik/prototypes/P300_visual_2_class_budzik_calibration_configs/config_server.ini @@ -0,0 +1,14 @@ + +[config_sources] + +[launch_dependencies] + +[external_params] + +[local_params] +experiment_uuid = +console_log_level = info +log_dir = ~/.obci/logs +mx_log_level = info +file_log_level = debug +sentry_log_level = error diff --git a/obci/scenarios/budzik/prototypes/P300_visual_2_class_budzik_calibration_configs/feedback.ini b/obci/scenarios/budzik/prototypes/P300_visual_2_class_budzik_calibration_configs/feedback.ini new file mode 100644 index 00000000..a26604ca --- /dev/null +++ b/obci/scenarios/budzik/prototypes/P300_visual_2_class_budzik_calibration_configs/feedback.ini @@ -0,0 +1,15 @@ + +[config_sources] + +[launch_dependencies] + +[external_params] + +[local_params] +experiment_uuid = +console_log_level = info +hello_message = Start BCI, wysłuchaj pytania i skup się na odpowiedzi +sentry_log_level = error +mx_log_level = info +file_log_level = debug +log_dir = ~/.obci/logs diff --git a/obci/scenarios/budzik/prototypes/P300_visual_2_class_budzik_calibration_configs/info_saver.ini b/obci/scenarios/budzik/prototypes/P300_visual_2_class_budzik_calibration_configs/info_saver.ini new file mode 100644 index 00000000..cb6640e0 --- /dev/null +++ b/obci/scenarios/budzik/prototypes/P300_visual_2_class_budzik_calibration_configs/info_saver.ini @@ -0,0 +1,14 @@ + +[config_sources] + +[launch_dependencies] + +[external_params] + +[local_params] +experiment_uuid = +console_log_level = info +log_dir = ~/.obci/logs +mx_log_level = info +file_log_level = debug +sentry_log_level = error diff --git a/obci/scenarios/budzik/prototypes/P300_visual_2_class_budzik_calibration_configs/logic.ini b/obci/scenarios/budzik/prototypes/P300_visual_2_class_budzik_calibration_configs/logic.ini new file mode 100644 index 00000000..cd28fc51 --- /dev/null +++ b/obci/scenarios/budzik/prototypes/P300_visual_2_class_budzik_calibration_configs/logic.ini @@ -0,0 +1,16 @@ + +[config_sources] + +[launch_dependencies] +signal_saver = + +[external_params] + +[local_params] +experiment_uuid = +console_log_level = info +sentry_log_level = error +mx_log_level = info +file_log_level = debug +trials_count = 12 +log_dir = ~/.obci/logs diff --git a/obci/scenarios/budzik/prototypes/P300_visual_2_class_budzik_calibration_configs/mx.ini b/obci/scenarios/budzik/prototypes/P300_visual_2_class_budzik_calibration_configs/mx.ini new file mode 100644 index 00000000..cb6640e0 --- /dev/null +++ b/obci/scenarios/budzik/prototypes/P300_visual_2_class_budzik_calibration_configs/mx.ini @@ -0,0 +1,14 @@ + +[config_sources] + +[launch_dependencies] + +[external_params] + +[local_params] +experiment_uuid = +console_log_level = info +log_dir = ~/.obci/logs +mx_log_level = info +file_log_level = debug +sentry_log_level = error diff --git a/obci/scenarios/budzik/prototypes/P300_visual_2_class_budzik_calibration_configs/signal_saver.ini b/obci/scenarios/budzik/prototypes/P300_visual_2_class_budzik_calibration_configs/signal_saver.ini new file mode 100644 index 00000000..cd1348d6 --- /dev/null +++ b/obci/scenarios/budzik/prototypes/P300_visual_2_class_budzik_calibration_configs/signal_saver.ini @@ -0,0 +1,15 @@ + +[config_sources] + +[launch_dependencies] + +[external_params] + +[local_params] +experiment_uuid = +save_file_name = test2 +console_log_level = info +sentry_log_level = error +mx_log_level = info +file_log_level = debug +log_dir = ~/.obci/logs diff --git a/obci/scenarios/budzik/prototypes/P300_visual_2_class_budzik_calibration_configs/tag_saver.ini b/obci/scenarios/budzik/prototypes/P300_visual_2_class_budzik_calibration_configs/tag_saver.ini new file mode 100644 index 00000000..cb6640e0 --- /dev/null +++ b/obci/scenarios/budzik/prototypes/P300_visual_2_class_budzik_calibration_configs/tag_saver.ini @@ -0,0 +1,14 @@ + +[config_sources] + +[launch_dependencies] + +[external_params] + +[local_params] +experiment_uuid = +console_log_level = info +log_dir = ~/.obci/logs +mx_log_level = info +file_log_level = debug +sentry_log_level = error diff --git a/obci/scenarios/budzik/prototypes/P300_visual_2_class_budzik_calibration_configs/ugm_engine.ini b/obci/scenarios/budzik/prototypes/P300_visual_2_class_budzik_calibration_configs/ugm_engine.ini new file mode 100644 index 00000000..33f187ae --- /dev/null +++ b/obci/scenarios/budzik/prototypes/P300_visual_2_class_budzik_calibration_configs/ugm_engine.ini @@ -0,0 +1,32 @@ + +[config_sources] +logic = + +[launch_dependencies] + +[external_params] + +[local_params] +ugm_config = budzik_visual_p300_2class +blink_ugm_id_start = 1001 +modalities = visual +running_on_start = 0 +haptic_duration = 0.8 +blink_ugm_key = font_color +blink_count_type = random +sentry_log_level = error +blink_ugm_value = #E42525 +log_dir = ~/.obci/logs +blink_count_min = 5 +blink_count_max = 10 +global_target_proba = 0.3 +console_log_level = info +file_log_level = debug +mx_log_level = info +experiment_uuid = +active_field_ids = 0;1 +blink_max_break = 0.22 +blink_min_break = 0.18 +blink_id_count = 2 +blink_ugm_id_count = 2 +blink_ugm_type = singletextimageoddball diff --git a/obci/scenarios/budzik/prototypes/P300_visual_2_class_budzik_calibration_configs/ugm_engine_amp.ini b/obci/scenarios/budzik/prototypes/P300_visual_2_class_budzik_calibration_configs/ugm_engine_amp.ini new file mode 100644 index 00000000..2ccbd9d3 --- /dev/null +++ b/obci/scenarios/budzik/prototypes/P300_visual_2_class_budzik_calibration_configs/ugm_engine_amp.ini @@ -0,0 +1,34 @@ + +[config_sources] +logic = + +[launch_dependencies] + +[external_params] + +[local_params] +blink_duration=0.15 +target_image_path=obci.gui.ugm.resources.einstein.png +ugm_config = budzik_visual_p300_2class +blink_ugm_id_start = 1001 +modalities = visual +running_on_start = 0 +haptic_duration = 0.8 +blink_ugm_key = font_color +blink_count_type = random +sentry_log_level = error +blink_ugm_value = #E42525 +log_dir = ~/.obci/logs +blink_count_min = 10 +blink_count_max = 15 +global_target_proba = 0.4 +console_log_level = info +file_log_level = debug +mx_log_level = info +experiment_uuid = +active_field_ids = 0;1 +blink_max_break = 0.22 +blink_min_break = 0.18 +blink_id_count = 2 +blink_ugm_id_count = 2 +blink_ugm_type = singletextimageoddball diff --git a/obci/scenarios/budzik/prototypes/P300_visual_2_class_budzik_calibration_configs/ugm_server.ini b/obci/scenarios/budzik/prototypes/P300_visual_2_class_budzik_calibration_configs/ugm_server.ini new file mode 100644 index 00000000..cb6640e0 --- /dev/null +++ b/obci/scenarios/budzik/prototypes/P300_visual_2_class_budzik_calibration_configs/ugm_server.ini @@ -0,0 +1,14 @@ + +[config_sources] + +[launch_dependencies] + +[external_params] + +[local_params] +experiment_uuid = +console_log_level = info +log_dir = ~/.obci/logs +mx_log_level = info +file_log_level = debug +sentry_log_level = error diff --git a/obci/scenarios/budzik/prototypes/P300_visual_2_class_budzik_configs/amplifier.ini b/obci/scenarios/budzik/prototypes/P300_visual_2_class_budzik_configs/amplifier.ini new file mode 100644 index 00000000..2fa97c86 --- /dev/null +++ b/obci/scenarios/budzik/prototypes/P300_visual_2_class_budzik_configs/amplifier.ini @@ -0,0 +1,17 @@ + +[config_sources] + +[launch_dependencies] + +[external_params] + +[local_params] +active_channels = 0;1;2;3;4;5;6;7;8;Saw;Driver_Saw +channel_names = PO7;O1;Oz;O2;PO8;PO3;PO4;Pz;Cz;AmpSaw;DriverSaw +experiment_uuid = +console_log_level = info +log_dir = ~/.obci/logs +mx_log_level = info +file_log_level = debug +sampling_rate = 512 +sentry_log_level = error diff --git a/obci/scenarios/budzik/prototypes/P300_visual_2_class_budzik_configs/analysis.ini b/obci/scenarios/budzik/prototypes/P300_visual_2_class_budzik_configs/analysis.ini new file mode 100644 index 00000000..9489a15b --- /dev/null +++ b/obci/scenarios/budzik/prototypes/P300_visual_2_class_budzik_configs/analysis.ini @@ -0,0 +1,17 @@ + +[config_sources] + +[launch_dependencies] + +[external_params] + +[local_params] +experiment_uuid = +console_log_level = info +channels_for_classification = O1;O2;Pz;Cz +log_dir = ~/.obci/logs +offline_learning = 0 +mx_log_level = info +file_log_level = debug +downsample_to = 24 +sentry_log_level = error diff --git a/obci/scenarios/budzik/prototypes/P300_visual_2_class_budzik_configs/analysis_amp.ini b/obci/scenarios/budzik/prototypes/P300_visual_2_class_budzik_configs/analysis_amp.ini new file mode 100644 index 00000000..9c5482cd --- /dev/null +++ b/obci/scenarios/budzik/prototypes/P300_visual_2_class_budzik_configs/analysis_amp.ini @@ -0,0 +1,19 @@ + +[config_sources] + +[launch_dependencies] + +[external_params] + +[local_params] +experiment_uuid = +console_log_level = info +channels_for_classification = O1;O2;Pz;Cz;M1;M2 +montage_channels=M1;M2 +log_dir = ~/.obci/logs +offline_learning = 0 +mx_log_level = info +file_log_level = debug +downsample_to = 24 +sentry_log_level = error +calibration_field_index = diff --git a/obci/scenarios/budzik/prototypes/P300_visual_2_class_budzik_configs/blink_catcher.ini b/obci/scenarios/budzik/prototypes/P300_visual_2_class_budzik_configs/blink_catcher.ini new file mode 100644 index 00000000..cb6640e0 --- /dev/null +++ b/obci/scenarios/budzik/prototypes/P300_visual_2_class_budzik_configs/blink_catcher.ini @@ -0,0 +1,14 @@ + +[config_sources] + +[launch_dependencies] + +[external_params] + +[local_params] +experiment_uuid = +console_log_level = info +log_dir = ~/.obci/logs +mx_log_level = info +file_log_level = debug +sentry_log_level = error diff --git a/obci/scenarios/budzik/prototypes/P300_visual_2_class_budzik_configs/config_server.ini b/obci/scenarios/budzik/prototypes/P300_visual_2_class_budzik_configs/config_server.ini new file mode 100644 index 00000000..cb6640e0 --- /dev/null +++ b/obci/scenarios/budzik/prototypes/P300_visual_2_class_budzik_configs/config_server.ini @@ -0,0 +1,14 @@ + +[config_sources] + +[launch_dependencies] + +[external_params] + +[local_params] +experiment_uuid = +console_log_level = info +log_dir = ~/.obci/logs +mx_log_level = info +file_log_level = debug +sentry_log_level = error diff --git a/obci/scenarios/budzik/prototypes/P300_visual_2_class_budzik_configs/feedback.ini b/obci/scenarios/budzik/prototypes/P300_visual_2_class_budzik_configs/feedback.ini new file mode 100644 index 00000000..139b81a8 --- /dev/null +++ b/obci/scenarios/budzik/prototypes/P300_visual_2_class_budzik_configs/feedback.ini @@ -0,0 +1,15 @@ + +[config_sources] + +[launch_dependencies] + +[external_params] + +[local_params] +hello_message=Start BCI, wysłuchaj pytania i skup się na odpowiedzi +experiment_uuid = +console_log_level = info +log_dir = ~/.obci/logs +mx_log_level = info +file_log_level = debug +sentry_log_level = error diff --git a/obci/scenarios/budzik/prototypes/P300_visual_2_class_budzik_configs/info_saver.ini b/obci/scenarios/budzik/prototypes/P300_visual_2_class_budzik_configs/info_saver.ini new file mode 100644 index 00000000..cb6640e0 --- /dev/null +++ b/obci/scenarios/budzik/prototypes/P300_visual_2_class_budzik_configs/info_saver.ini @@ -0,0 +1,14 @@ + +[config_sources] + +[launch_dependencies] + +[external_params] + +[local_params] +experiment_uuid = +console_log_level = info +log_dir = ~/.obci/logs +mx_log_level = info +file_log_level = debug +sentry_log_level = error diff --git a/obci/scenarios/budzik/prototypes/P300_visual_2_class_budzik_configs/logic.ini b/obci/scenarios/budzik/prototypes/P300_visual_2_class_budzik_configs/logic.ini new file mode 100644 index 00000000..02bf4bc9 --- /dev/null +++ b/obci/scenarios/budzik/prototypes/P300_visual_2_class_budzik_configs/logic.ini @@ -0,0 +1,19 @@ + +[config_sources] + +[launch_dependencies] +signal_saver = + +[external_params] + +[local_params] +experiment_uuid = +active_field_ids = 0;2;5 +dec_count = 3 +logic_decision_config = obci.logic.configs.config_maze_rovio.Config +robot_ip = 192.168.1.18 +console_log_level = info +sentry_log_level = error +mx_log_level = info +file_log_level = debug +log_dir = ~/.obci/logs diff --git a/obci/scenarios/budzik/prototypes/P300_visual_2_class_budzik_configs/mx.ini b/obci/scenarios/budzik/prototypes/P300_visual_2_class_budzik_configs/mx.ini new file mode 100644 index 00000000..cb6640e0 --- /dev/null +++ b/obci/scenarios/budzik/prototypes/P300_visual_2_class_budzik_configs/mx.ini @@ -0,0 +1,14 @@ + +[config_sources] + +[launch_dependencies] + +[external_params] + +[local_params] +experiment_uuid = +console_log_level = info +log_dir = ~/.obci/logs +mx_log_level = info +file_log_level = debug +sentry_log_level = error diff --git a/obci/scenarios/budzik/prototypes/P300_visual_2_class_budzik_configs/signal_saver.ini b/obci/scenarios/budzik/prototypes/P300_visual_2_class_budzik_configs/signal_saver.ini new file mode 100644 index 00000000..cd1348d6 --- /dev/null +++ b/obci/scenarios/budzik/prototypes/P300_visual_2_class_budzik_configs/signal_saver.ini @@ -0,0 +1,15 @@ + +[config_sources] + +[launch_dependencies] + +[external_params] + +[local_params] +experiment_uuid = +save_file_name = test2 +console_log_level = info +sentry_log_level = error +mx_log_level = info +file_log_level = debug +log_dir = ~/.obci/logs diff --git a/obci/scenarios/budzik/prototypes/P300_visual_2_class_budzik_configs/switch.ini b/obci/scenarios/budzik/prototypes/P300_visual_2_class_budzik_configs/switch.ini new file mode 100644 index 00000000..cb6640e0 --- /dev/null +++ b/obci/scenarios/budzik/prototypes/P300_visual_2_class_budzik_configs/switch.ini @@ -0,0 +1,14 @@ + +[config_sources] + +[launch_dependencies] + +[external_params] + +[local_params] +experiment_uuid = +console_log_level = info +log_dir = ~/.obci/logs +mx_log_level = info +file_log_level = debug +sentry_log_level = error diff --git a/obci/scenarios/budzik/prototypes/P300_visual_2_class_budzik_configs/switch_backup.ini b/obci/scenarios/budzik/prototypes/P300_visual_2_class_budzik_configs/switch_backup.ini new file mode 100644 index 00000000..81e49483 --- /dev/null +++ b/obci/scenarios/budzik/prototypes/P300_visual_2_class_budzik_configs/switch_backup.ini @@ -0,0 +1,15 @@ + +[config_sources] + +[launch_dependencies] + +[external_params] + +[local_params] +experiment_uuid = +console_log_level = info +log_dir = ~/.obci/logs +sentry_log_level = error +mx_log_level = info +file_log_level = debug +finish_saving = 1 diff --git a/obci/scenarios/budzik/prototypes/P300_visual_2_class_budzik_configs/tag_saver.ini b/obci/scenarios/budzik/prototypes/P300_visual_2_class_budzik_configs/tag_saver.ini new file mode 100644 index 00000000..cb6640e0 --- /dev/null +++ b/obci/scenarios/budzik/prototypes/P300_visual_2_class_budzik_configs/tag_saver.ini @@ -0,0 +1,14 @@ + +[config_sources] + +[launch_dependencies] + +[external_params] + +[local_params] +experiment_uuid = +console_log_level = info +log_dir = ~/.obci/logs +mx_log_level = info +file_log_level = debug +sentry_log_level = error diff --git a/obci/scenarios/budzik/prototypes/P300_visual_2_class_budzik_configs/ugm_engine.ini b/obci/scenarios/budzik/prototypes/P300_visual_2_class_budzik_configs/ugm_engine.ini new file mode 100644 index 00000000..47bb60fc --- /dev/null +++ b/obci/scenarios/budzik/prototypes/P300_visual_2_class_budzik_configs/ugm_engine.ini @@ -0,0 +1,31 @@ + +[config_sources] +logic = + +[launch_dependencies] + +[external_params] + +[local_params] +ugm_config = budzik_visual_p300_2class +blink_ugm_id_start = 1001 +modalities = visual +running_on_start = 0 +haptic_duration = 0.8 +blink_ugm_key = font_color +sentry_log_level = error +blink_ugm_value = #E42525 +log_dir = ~/.obci/logs +blink_count_min = 64 +blink_count_max = 80 +global_target_proba = 0.3 +console_log_level = info +file_log_level = debug +mx_log_level = info +experiment_uuid = +active_field_ids = 0;1 +blink_max_break = 0.22 +blink_min_break = 0.18 +blink_id_count = 2 +blink_ugm_id_count = 2 +blink_ugm_type = singletextimageoddball diff --git a/obci/scenarios/budzik/prototypes/P300_visual_2_class_budzik_configs/ugm_engine_amp.ini b/obci/scenarios/budzik/prototypes/P300_visual_2_class_budzik_configs/ugm_engine_amp.ini new file mode 100644 index 00000000..118157e8 --- /dev/null +++ b/obci/scenarios/budzik/prototypes/P300_visual_2_class_budzik_configs/ugm_engine_amp.ini @@ -0,0 +1,33 @@ + +[config_sources] +logic = + +[launch_dependencies] + +[external_params] + +[local_params] +blink_duration=0.15 +target_image_path=obci.gui.ugm.resources.einstein.png +ugm_config = budzik_visual_p300_2class +blink_ugm_id_start = 1001 +modalities = visual +running_on_start = 0 +haptic_duration = 0.8 +blink_ugm_key = font_color +sentry_log_level = error +blink_ugm_value = #E42525 +log_dir = ~/.obci/logs +blink_count_min = 64 +blink_count_max = 80 +global_target_proba = 0.4 +console_log_level = info +file_log_level = debug +mx_log_level = info +experiment_uuid = +active_field_ids = 0;1 +blink_max_break = 0.22 +blink_min_break = 0.18 +blink_id_count = 2 +blink_ugm_id_count = 2 +blink_ugm_type = singletextimageoddball diff --git a/obci/scenarios/budzik/prototypes/P300_visual_2_class_budzik_configs/ugm_server.ini b/obci/scenarios/budzik/prototypes/P300_visual_2_class_budzik_configs/ugm_server.ini new file mode 100644 index 00000000..cb6640e0 --- /dev/null +++ b/obci/scenarios/budzik/prototypes/P300_visual_2_class_budzik_configs/ugm_server.ini @@ -0,0 +1,14 @@ + +[config_sources] + +[launch_dependencies] + +[external_params] + +[local_params] +experiment_uuid = +console_log_level = info +log_dir = ~/.obci/logs +mx_log_level = info +file_log_level = debug +sentry_log_level = error diff --git a/obci/scenarios/budzik/prototypes/modal_p300/config/p300_all_modalities.ini b/obci/scenarios/budzik/prototypes/modal_p300/config/p300_all_modalities.ini new file mode 100644 index 00000000..5b3bb339 --- /dev/null +++ b/obci/scenarios/budzik/prototypes/modal_p300/config/p300_all_modalities.ini @@ -0,0 +1,53 @@ +[local_params] +ugm_config=brain2013_config_8_fields_tablet + +modalities=visual;auditory;haptic +; blinking engine params *************** +; visual +blink_duration=1 +running_on_start=1 + +;auditory +;should be in order of active_field_ids +soundfiles=~/dataset/sounds/1.wav;~/dataset/sounds/2.wav;~/dataset/sounds/3.wav + +;hapitc +haptic_duration=0.8 +haptic_device=0403:6010 +;in order of active_field_ids +haptic_channels_map=1;2;3 + + +; time manager +blink_min_break=0.08 +blink_max_break=0.12 + +; count manager +blink_count_type=inf +; inf, random, random_sequential, sequential +blink_count_min=64 +blink_count_max=80 + +; id manager +blink_id_type=random_sequential +; sequential, random, random_sequential +blink_id_count=3 + +; ugm manager +blink_ugm_id_start=1001 +blink_ugm_id_count=3 +blink_id_count=3 +active_field_ids=0;2;5 +blink_ugm_key=font_color +blink_ugm_value=#E42525 +;blink_ugm_value=#4c05ef + +blink_ugm_type=single +; single, classic + +; classic... +blink_ugm_row_count=2 +blink_ugm_col_count=4 + + + diff --git a/obci/scenarios/budzik/prototypes/modal_p300/p300_labyrinth_dummy.ini b/obci/scenarios/budzik/prototypes/modal_p300/p300_labyrinth_dummy.ini new file mode 100644 index 00000000..ba2d69a3 --- /dev/null +++ b/obci/scenarios/budzik/prototypes/modal_p300/p300_labyrinth_dummy.ini @@ -0,0 +1,96 @@ +[peers] +scenario_dir= +;*********************************************** +[peers.mx] +path=multiplexer-install/bin/mxcontrol + +;*********************************************** +[peers.config_server] +path=control/peer/config_server.py + +;*********************************************** +[peers.amplifier] +path=drivers/eeg/amplifier_virtual.py +config=scenarios/budzik/prototypes/p300_configs/cap_brain2013_dummy.ini + +;*********************************************** +[peers.signal_saver] +path=acquisition/signal_saver_peer.py +config=scenarios/budzik/prototypes/p300_configs/p300_labyrinth_signal_saver_config.ini + +[peers.signal_saver.launch_dependencies] +amplifier=amplifier + +;*********************************************** +[peers.tag_saver] +path=acquisition/tag_saver_peer.py + +[peers.tag_saver.launch_dependencies] +signal_saver=signal_saver + +;*********************************************** +[peers.info_saver] +path=acquisition/info_saver_peer.py + +[peers.info_saver.launch_dependencies] +amplifier=amplifier +signal_saver=signal_saver + +;*********************************************** +[peers.ugm_engine] +path=gui/ugm/blinking/ugm_modal_blinking_engine_peer.py +config=scenarios/budzik/prototypes/modal_p300/config/p300_all_modalities.ini + +[peers.ugm_engine.config_sources] +logic=logic + +;*********************************************** +[peers.ugm_server] +path=gui/ugm/ugm_server_peer.py + +[peers.ugm_server.launch_dependencies] +ugm_engine=ugm_engine + +;*********************************************** +[peers.analysis] +path=interfaces/bci/p300_MD/p300_master_peer.py +config=scenarios/budzik/prototypes/p300_configs/p300_labyrinth_clasifier_config.ini + +[peers.analysis.config_sources] +logic=logic +amplifier=amplifier + +[peers.analysis.launch_dependencies] +logic=logic +amplifier=amplifier + +;************************************************* +[peers.logic] +path=logic/logic_maze_peer.py +config=scenarios/brain2013/configs/brain2013_logic_maze_peer.ini + +[peers.logic.launch_dependencies] +ugm=ugm_server +signal_saver=signal_saver + +;************************************ +[peers.feedback] +path=logic/feedback/logic_decision_feedback_peer.py + +[peers.feedback.launch_dependencies] +ugm_engine=ugm_engine +ugm_server=ugm_server +logic=logic +analysis=analysis + +;*********************************************** +[peers.switch_backup] +path=interfaces/switch/backup/switch_backup_peer.py +config=scenarios/budzik/prototypes/p300_configs/p300_labyrinth_switch_config.ini + +;*********************************************** +[peers.switch] +path=drivers/switch/switch_amplifier_peer.py + +[peers.switch.launch_dependencies] +ugm_engine=ugm_engine diff --git a/obci/scenarios/budzik/prototypes/p300_configs/cap_brain2013_dummy.ini b/obci/scenarios/budzik/prototypes/p300_configs/cap_brain2013_dummy.ini new file mode 100644 index 00000000..7524e631 --- /dev/null +++ b/obci/scenarios/budzik/prototypes/p300_configs/cap_brain2013_dummy.ini @@ -0,0 +1,6 @@ +[local_params] +sampling_rate=512 +channel_names=PO7;O1;Oz;O2;PO8;PO3;PO4;Pz;Cz;AmpSaw;DriverSaw +active_channels=0;1;2;3;4;5;6;7;8;Saw;Driver_Saw + + diff --git a/obci/scenarios/budzik/prototypes/p300_configs/p300_amplifier_offline_calibration_config.ini b/obci/scenarios/budzik/prototypes/p300_configs/p300_amplifier_offline_calibration_config.ini new file mode 100644 index 00000000..90213c80 --- /dev/null +++ b/obci/scenarios/budzik/prototypes/p300_configs/p300_amplifier_offline_calibration_config.ini @@ -0,0 +1,7 @@ +[local_params] +data_file_dir=~/dataset/ +data_file_name=diody3 +info_file_dir= +info_file_name= +tags_file_dir= +tags_file_name= diff --git a/obci/scenarios/budzik/prototypes/p300_configs/p300_classifier_synthetic_calibration_config.ini b/obci/scenarios/budzik/prototypes/p300_configs/p300_classifier_synthetic_calibration_config.ini new file mode 100644 index 00000000..68d39c0b --- /dev/null +++ b/obci/scenarios/budzik/prototypes/p300_configs/p300_classifier_synthetic_calibration_config.ini @@ -0,0 +1,24 @@ +[local_params] +wisdom_path=~/classifier_synthetic.dump +channels_for_classification=O1;O2;Pz;Cz +montage_channels=Cz +baseline=-0.2 +window=0.5 +maximum_to_average=10 +decision_stop=3 +downsample_to=24 +;which field is used in online calibration +calibration_field_index=1 +;if want to run offline calibration provide this file: +offline_learning=0 +offline_learning_dataset_path= + +[config_sources] +amplifier= + +[external_params] +channel_names=amplifier.channel_names +sampling_rate=amplifier.sampling_rate + +[launch_dependencies] +amplifier= diff --git a/obci/scenarios/budzik/prototypes/p300_configs/p300_classifier_synthetic_test_config.ini b/obci/scenarios/budzik/prototypes/p300_configs/p300_classifier_synthetic_test_config.ini new file mode 100644 index 00000000..ce8a6a82 --- /dev/null +++ b/obci/scenarios/budzik/prototypes/p300_configs/p300_classifier_synthetic_test_config.ini @@ -0,0 +1,24 @@ +[local_params] +wisdom_path=~/classifier_synthetic.dump +channels_for_classification=O1;O2;Pz;Cz +montage_channels=Cz +baseline=-0.2 +window=0.5 +maximum_to_average=10 +decision_stop=3 +downsample_to=24 +;which field is used in online calibration +calibration_field_index= +;if want to run offline calibration provide this file: +offline_learning=0 +offline_learning_dataset_path= + +[config_sources] +amplifier= + +[external_params] +channel_names=amplifier.channel_names +sampling_rate=amplifier.sampling_rate + +[launch_dependencies] +amplifier= diff --git a/obci/scenarios/budzik/prototypes/p300_configs/p300_labyrinth_clasifier_config.ini b/obci/scenarios/budzik/prototypes/p300_configs/p300_labyrinth_clasifier_config.ini new file mode 100644 index 00000000..f7ac8565 --- /dev/null +++ b/obci/scenarios/budzik/prototypes/p300_configs/p300_labyrinth_clasifier_config.ini @@ -0,0 +1,25 @@ +[local_params] +wisdom_path=~/classifier.dump +channels_for_classification=O1;O2;Pz;Cz +montage_channels=Cz +baseline=-0.2 +window=0.5 +maximum_to_average=10 +decision_stop=3 +downsample_to=24 +;which field is used in online calibration +calibration_field_index= +;if want to run offline calibration provide this file: +offline_learning=0 +offline_learning_dataset_path= + +[config_sources] +amplifier= + +[external_params] +channel_names=amplifier.channel_names +sampling_rate=amplifier.sampling_rate + +[launch_dependencies] +amplifier= + diff --git a/obci/scenarios/budzik/prototypes/p300_configs/p300_labyrinth_signal_saver_config.ini b/obci/scenarios/budzik/prototypes/p300_configs/p300_labyrinth_signal_saver_config.ini new file mode 100644 index 00000000..9de26e07 --- /dev/null +++ b/obci/scenarios/budzik/prototypes/p300_configs/p300_labyrinth_signal_saver_config.ini @@ -0,0 +1,2 @@ +[local_params] +save_file_name=test2 diff --git a/obci/scenarios/budzik/prototypes/p300_configs/p300_labyrinth_switch_config.ini b/obci/scenarios/budzik/prototypes/p300_configs/p300_labyrinth_switch_config.ini new file mode 100644 index 00000000..0ef39675 --- /dev/null +++ b/obci/scenarios/budzik/prototypes/p300_configs/p300_labyrinth_switch_config.ini @@ -0,0 +1,2 @@ +[local_params] +finish_saving=1 diff --git a/obci/scenarios/budzik/prototypes/p300_configs/p300_offline_calibration_config.ini b/obci/scenarios/budzik/prototypes/p300_configs/p300_offline_calibration_config.ini new file mode 100644 index 00000000..b8611ac0 --- /dev/null +++ b/obci/scenarios/budzik/prototypes/p300_configs/p300_offline_calibration_config.ini @@ -0,0 +1,24 @@ +[local_params] +wisdom_path=~/classifier.dump +channels_for_classification=O1;O2;P3;P4 +montage_channels=ref +baseline=-0.2 +window=0.5 +maximum_to_average=10 +decision_stop=3 +downsample_to=24 +;which field is used in online calibration +calibration_field_index= +;if want to run offline calibration provide this file: +offline_learning=1 +offline_learning_dataset_path=~/dataset/diody3.obci + +[config_sources] +amplifier= + +[external_params] +channel_names=amplifier.channel_names +sampling_rate=amplifier.sampling_rate + +[launch_dependencies] +amplifier= diff --git a/obci/scenarios/budzik/prototypes/p300_configs/p300_tag_catcher_synthetic_test_config.ini b/obci/scenarios/budzik/prototypes/p300_configs/p300_tag_catcher_synthetic_test_config.ini new file mode 100644 index 00000000..16a9031c --- /dev/null +++ b/obci/scenarios/budzik/prototypes/p300_configs/p300_tag_catcher_synthetic_test_config.ini @@ -0,0 +1,8 @@ +[config_sources] +ugm_engine= + +[external_params] +blink_duration=ugm_engine.blink_duration + +[launch_dependencies] +ugm_engine= diff --git a/obci/scenarios/budzik/prototypes/p300_labyrinth.ini b/obci/scenarios/budzik/prototypes/p300_labyrinth.ini new file mode 100644 index 00000000..f0745856 --- /dev/null +++ b/obci/scenarios/budzik/prototypes/p300_labyrinth.ini @@ -0,0 +1,96 @@ +[peers] +scenario_dir= +;*********************************************** +[peers.mx] +path=multiplexer-install/bin/mxcontrol + +;*********************************************** +[peers.config_server] +path=control/peer/config_server.py + +;*********************************************** +[peers.amplifier] +path=drivers/eeg/cpp_amplifiers/amplifier_tmsi.py +config=scenarios/brain2013/configs/cap_brain2013.ini + +;*********************************************** +[peers.signal_saver] +path=acquisition/signal_saver_peer.py +config=scenarios/p300_MD/configs/p300_labyrinth_signal_saver_config.ini + +[peers.signal_saver.launch_dependencies] +amplifier=amplifier + +;*********************************************** +[peers.tag_saver] +path=acquisition/tag_saver_peer.py + +[peers.tag_saver.launch_dependencies] +signal_saver=signal_saver + +;*********************************************** +[peers.info_saver] +path=acquisition/info_saver_peer.py + +[peers.info_saver.launch_dependencies] +amplifier=amplifier +signal_saver=signal_saver + +;*********************************************** +[peers.ugm_engine] +path=gui/ugm/blinking/ugm_blinking_engine_peer.py +config=scenarios/brain2013/configs/p300_fast_colour_bci.ini + +[peers.ugm_engine.config_sources] +logic=logic + +;*********************************************** +[peers.ugm_server] +path=gui/ugm/ugm_server_peer.py + +[peers.ugm_server.launch_dependencies] +ugm_engine=ugm_engine + +;*********************************************** +[peers.analysis] +path=interfaces/bci/p300_MD/p300_master_peer.py +config=scenarios/budzik/prototypes/p300_configs/p300_labyrinth_clasifier_config.ini + +[peers.analysis.config_sources] +logic=logic +amplifier=amplifier + +[peers.analysis.launch_dependencies] +logic=logic +amplifier=amplifier + +;************************************************* +[peers.logic] +path=logic/logic_maze_peer.py +config=scenarios/brain2013/configs/brain2013_logic_maze_peer.ini + +[peers.logic.launch_dependencies] +ugm=ugm_server +signal_saver=signal_saver + +;************************************ +[peers.feedback] +path=logic/feedback/logic_decision_feedback_peer.py + +[peers.feedback.launch_dependencies] +ugm_engine=ugm_engine +ugm_server=ugm_server +logic=logic +analysis=analysis + +;*********************************************** +[peers.switch_backup] +path=interfaces/switch/backup/switch_backup_peer.py +config=scenarios/p300_MD/configs/p300_labyrinth_switch_config.ini + +;*********************************************** +[peers.switch] +path=drivers/switch/switch_amplifier_peer.py + +[peers.switch.launch_dependencies] +ugm_engine=ugm_engine diff --git a/obci/scenarios/budzik/prototypes/p300_labyrinth_dummy.ini b/obci/scenarios/budzik/prototypes/p300_labyrinth_dummy.ini new file mode 100644 index 00000000..305c7130 --- /dev/null +++ b/obci/scenarios/budzik/prototypes/p300_labyrinth_dummy.ini @@ -0,0 +1,96 @@ +[peers] +scenario_dir= +;*********************************************** +[peers.mx] +path=multiplexer-install/bin/mxcontrol + +;*********************************************** +[peers.config_server] +path=control/peer/config_server.py + +;*********************************************** +[peers.amplifier] +path=drivers/eeg/amplifier_virtual.py +config=scenarios/budzik/prototypes/p300_configs/cap_brain2013_dummy.ini + +;*********************************************** +[peers.signal_saver] +path=acquisition/signal_saver_peer.py +config=scenarios/budzik/prototypes/p300_configs/p300_labyrinth_signal_saver_config.ini + +[peers.signal_saver.launch_dependencies] +amplifier=amplifier + +;*********************************************** +[peers.tag_saver] +path=acquisition/tag_saver_peer.py + +[peers.tag_saver.launch_dependencies] +signal_saver=signal_saver + +;*********************************************** +[peers.info_saver] +path=acquisition/info_saver_peer.py + +[peers.info_saver.launch_dependencies] +amplifier=amplifier +signal_saver=signal_saver + +;*********************************************** +[peers.ugm_engine] +path=gui/ugm/blinking/ugm_blinking_engine_peer.py +config=scenarios/brain2013/configs/p300_fast_colour_bci.ini + +[peers.ugm_engine.config_sources] +logic=logic + +;*********************************************** +[peers.ugm_server] +path=gui/ugm/ugm_server_peer.py + +[peers.ugm_server.launch_dependencies] +ugm_engine=ugm_engine + +;*********************************************** +[peers.analysis] +path=interfaces/bci/p300_MD/p300_master_peer.py +config=scenarios/budzik/prototypes/p300_configs/p300_labyrinth_clasifier_config.ini + +[peers.analysis.config_sources] +logic=logic +amplifier=amplifier + +[peers.analysis.launch_dependencies] +logic=logic +amplifier=amplifier + +;************************************************* +[peers.logic] +path=logic/logic_maze_peer.py +config=scenarios/brain2013/configs/brain2013_logic_maze_peer.ini + +[peers.logic.launch_dependencies] +ugm=ugm_server +signal_saver=signal_saver + +;************************************ +[peers.feedback] +path=logic/feedback/logic_decision_feedback_peer.py + +[peers.feedback.launch_dependencies] +ugm_engine=ugm_engine +ugm_server=ugm_server +logic=logic +analysis=analysis + +;*********************************************** +[peers.switch_backup] +path=interfaces/switch/backup/switch_backup_peer.py +config=scenarios/budzik/prototypes/p300_configs/p300_labyrinth_switch_config.ini + +;*********************************************** +[peers.switch] +path=drivers/switch/switch_amplifier_peer.py + +[peers.switch.launch_dependencies] +ugm_engine=ugm_engine diff --git a/obci/scenarios/budzik/prototypes/p300_online_synthetic_real_data_test.ini b/obci/scenarios/budzik/prototypes/p300_online_synthetic_real_data_test.ini new file mode 100644 index 00000000..8885f232 --- /dev/null +++ b/obci/scenarios/budzik/prototypes/p300_online_synthetic_real_data_test.ini @@ -0,0 +1,35 @@ +[peers] +scenario_dir = + +[peers.blink_catcher] +path = utils/blink_catcher_peer.py +config = scenarios/budzik/prototypes/p300_online_synthetic_real_data_test_configs/blink_catcher.ini + +[peers.blink_catcher.config_sources] +ugm_engine = amplifier + +[peers.blink_catcher.launch_dependencies] +ugm_engine = amplifier + +[peers.amplifier] +path = interfaces/bci/p300_MD/tests/synthetic_generator.py +config =scenarios/budzik/prototypes/p300_online_synthetic_real_data_test_configs/amplifier.ini + +[peers.mx] +path = multiplexer-install/bin/mxcontrol +config = scenarios/budzik/prototypes/p300_online_synthetic_real_data_test_configs/mx.ini + +[peers.analysis] +path = interfaces/bci/p300_MD/p300_master_peer.py +config = scenarios/budzik/prototypes/p300_online_synthetic_real_data_test_configs/analysis.ini + +[peers.analysis.config_sources] +amplifier = amplifier + +[peers.analysis.launch_dependencies] +amplifier = amplifier + +[peers.config_server] +path = control/peer/config_server.py +config = scenarios/budzik/prototypes/p300_online_synthetic_real_data_test_configs/config_server.ini + diff --git a/obci/scenarios/budzik/prototypes/p300_online_synthetic_real_data_test_configs/amplifier.ini b/obci/scenarios/budzik/prototypes/p300_online_synthetic_real_data_test_configs/amplifier.ini new file mode 100644 index 00000000..47c908e7 --- /dev/null +++ b/obci/scenarios/budzik/prototypes/p300_online_synthetic_real_data_test_configs/amplifier.ini @@ -0,0 +1,21 @@ + +[config_sources] + +[launch_dependencies] + +[external_params] + +[local_params] +synthetic = 0 +targets_path = ~/dataset/nonsythetic/targets.npy +active_channels = 0;1;2;3;4;5;6;7;8;9;10;11;12;13;14;15;16;17;18;19 +statistics_path = ~/real_results +channel_names = T5;O1;O2;T6;P3;Pz;P4;T3;C3;Cz;C4;T4;F7;F3;Fz;F4;F8;Fp1;Fp2;ref +experiment_uuid = +meta_path = ~/dataset/nonsythetic/meta.json +nontargets_path = ~/dataset/nonsythetic/nontargets.npy +console_log_level = info +log_dir = ~/.obci/logs +mx_log_level = info +file_log_level = debug +sentry_log_level = error diff --git a/obci/scenarios/budzik/prototypes/p300_online_synthetic_real_data_test_configs/analysis.ini b/obci/scenarios/budzik/prototypes/p300_online_synthetic_real_data_test_configs/analysis.ini new file mode 100644 index 00000000..571c3727 --- /dev/null +++ b/obci/scenarios/budzik/prototypes/p300_online_synthetic_real_data_test_configs/analysis.ini @@ -0,0 +1,18 @@ + +[config_sources] + +[launch_dependencies] + +[external_params] + +[local_params] +experiment_uuid = +console_log_level = info +file_log_level = debug +montage_channels = ref +sentry_log_level = error +offline_learning = 0 +mx_log_level = info +channels_for_classification = O1;O2;P3;P4 +log_dir = ~/.obci/logs +downsample_to = 24 diff --git a/obci/scenarios/budzik/prototypes/p300_online_synthetic_real_data_test_configs/blink_catcher.ini b/obci/scenarios/budzik/prototypes/p300_online_synthetic_real_data_test_configs/blink_catcher.ini new file mode 100644 index 00000000..a1fff3bd --- /dev/null +++ b/obci/scenarios/budzik/prototypes/p300_online_synthetic_real_data_test_configs/blink_catcher.ini @@ -0,0 +1,14 @@ + +[config_sources] + +[launch_dependencies] + +[external_params] + +[local_params] +experiment_uuid = +console_log_level = info +log_dir = ~/.obci/logs +mx_log_level = error +file_log_level = debug +sentry_log_level = error diff --git a/obci/scenarios/budzik/prototypes/p300_online_synthetic_real_data_test_configs/config_server.ini b/obci/scenarios/budzik/prototypes/p300_online_synthetic_real_data_test_configs/config_server.ini new file mode 100644 index 00000000..a1fff3bd --- /dev/null +++ b/obci/scenarios/budzik/prototypes/p300_online_synthetic_real_data_test_configs/config_server.ini @@ -0,0 +1,14 @@ + +[config_sources] + +[launch_dependencies] + +[external_params] + +[local_params] +experiment_uuid = +console_log_level = info +log_dir = ~/.obci/logs +mx_log_level = error +file_log_level = debug +sentry_log_level = error diff --git a/obci/scenarios/budzik/prototypes/p300_online_synthetic_real_data_test_configs/mx.ini b/obci/scenarios/budzik/prototypes/p300_online_synthetic_real_data_test_configs/mx.ini new file mode 100644 index 00000000..cb6640e0 --- /dev/null +++ b/obci/scenarios/budzik/prototypes/p300_online_synthetic_real_data_test_configs/mx.ini @@ -0,0 +1,14 @@ + +[config_sources] + +[launch_dependencies] + +[external_params] + +[local_params] +experiment_uuid = +console_log_level = info +log_dir = ~/.obci/logs +mx_log_level = info +file_log_level = debug +sentry_log_level = error diff --git a/obci/scenarios/budzik/prototypes/p300_synthetic_test_online.ini b/obci/scenarios/budzik/prototypes/p300_synthetic_test_online.ini new file mode 100644 index 00000000..bb32283c --- /dev/null +++ b/obci/scenarios/budzik/prototypes/p300_synthetic_test_online.ini @@ -0,0 +1,31 @@ +[peers] +scenario_dir= +;*********************************************** +[peers.mx] +path=multiplexer-install/bin/mxcontrol + +;*********************************************** +[peers.config_server] +path=control/peer/config_server.py + +;*********************************************** +[peers.amplifier] +path=interfaces/bci/p300_MD/tests/synthetic_generator.py + +;*********************************************** +[peers.analysis] +path=interfaces/bci/p300_MD/p300_master_peer.py +config=scenarios/budzik/prototypes/p300_configs/p300_classifier_synthetic_test_config.ini + +[peers.analysis.config_sources] +amplifier=amplifier + +[peers.analysis.launch_dependencies] +amplifier=amplifier + +[peers.blink_catcher] +path=utils/blink_catcher_peer.py +config=scenarios/budzik/prototypes/p300_configs/p300_tag_catcher_synthetic_test_config.ini +[peers.blink_catcher.launch_dependencies] +ugm_engine=amplifier + diff --git a/obci/scenarios/budzik/prototypes/p300_visual_8_classes.ini b/obci/scenarios/budzik/prototypes/p300_visual_8_classes.ini new file mode 100644 index 00000000..0e62c654 --- /dev/null +++ b/obci/scenarios/budzik/prototypes/p300_visual_8_classes.ini @@ -0,0 +1,97 @@ +[peers] +scenario_dir = + +[peers.feedback] +path = logic/feedback/logic_decision_feedback_budzik_peer.py +config = scenarios/budzik/prototypes/p300_visual_8_classes_configs/feedback.ini + +[peers.feedback.config_sources] +ugm_engine = ugm_engine +analysis = analysis + +[peers.feedback.launch_dependencies] +ugm_server = ugm_server +ugm_engine = ugm_engine +analysis = analysis + +[peers.tag_saver] +path = acquisition/tag_saver_peer.py +config = scenarios/budzik/prototypes/p300_visual_8_classes_configs/tag_saver.ini + +[peers.tag_saver.config_sources] +signal_saver = signal_saver + +[peers.tag_saver.launch_dependencies] +signal_saver = signal_saver + +[peers.amplifier] +path = drivers/eeg/cpp_amplifiers/amplifier_tmsi.py +config = scenarios/budzik/prototypes/p300_visual_8_classes_configs/amplifier.ini + +[peers.config_server] +path = control/peer/config_server.py +config = scenarios/budzik/prototypes/p300_visual_8_classes_configs/config_server.ini + +[peers.analysis] +path = interfaces/bci/p300_MD/p300_master_peer.py +config = scenarios/budzik/prototypes/p300_visual_8_classes_configs/analysis.ini + +[peers.analysis.config_sources] +amplifier = amplifier + +[peers.analysis.launch_dependencies] +amplifier = amplifier + +[peers.ugm_server] +path = gui/ugm/ugm_server_peer.py +config = scenarios/budzik/prototypes/p300_visual_8_classes_configs/ugm_server.ini + +[peers.ugm_server.config_sources] +ugm_engine = ugm_engine + +[peers.ugm_server.launch_dependencies] +ugm_engine = ugm_engine + +[peers.info_saver] +path = acquisition/info_saver_peer.py +config = scenarios/budzik/prototypes/p300_visual_8_classes_configs/info_saver.ini + +[peers.info_saver.config_sources] +signal_saver = signal_saver +amplifier = amplifier + +[peers.info_saver.launch_dependencies] +signal_saver = signal_saver +amplifier = amplifier + +[peers.signal_saver] +path = acquisition/signal_saver_peer.py +config = scenarios/budzik/prototypes/p300_visual_8_classes_configs/signal_saver.ini + +[peers.signal_saver.config_sources] +amplifier = amplifier + +[peers.signal_saver.launch_dependencies] +amplifier = amplifier + +[peers.ugm_engine] +path = gui/ugm/blinking/ugm_modal_blinking_engine_peer.py +config = scenarios/budzik/prototypes/p300_visual_8_classes_configs/ugm_engine.ini + +[peers.ugm_engine.config_sources] +logic = + +[peers.mx] +path = multiplexer-install/bin/mxcontrol +config = scenarios/budzik/prototypes/p300_visual_8_classes_configs/mx.ini + +[peers.blink_catcher] +path = utils/blink_catcher_peer.py +config = scenarios/budzik/prototypes/p300_visual_8_classes_configs/blink_catcher.ini + +[peers.blink_catcher.config_sources] +ugm_engine = ugm_engine + +[peers.blink_catcher.launch_dependencies] +ugm_engine = ugm_engine + diff --git a/obci/scenarios/budzik/prototypes/p300_visual_8_classes_configs/amplifier.ini b/obci/scenarios/budzik/prototypes/p300_visual_8_classes_configs/amplifier.ini new file mode 100644 index 00000000..8d098d22 --- /dev/null +++ b/obci/scenarios/budzik/prototypes/p300_visual_8_classes_configs/amplifier.ini @@ -0,0 +1,17 @@ + +[config_sources] + +[launch_dependencies] + +[external_params] + +[local_params] +channel_names=Fp1;Fpz;Fp2;F7;F3;Fz;F4;F8;M1;T3;C3;Cz;C4;T4;M2;T5;P3;Pz;P4;T6;O1;Oz;O2;l_reka;p_reka;l_noga;eog;haptic1;haptic2;phones +active_channels=0;1;2;3;4;5;6;7;8;9;10;11;12;13;14;15;16;17;18;19;20;21;22;24;25;26;27;28;29;30 +experiment_uuid = +console_log_level = info +log_dir = ~/.obci/logs +mx_log_level = info +file_log_level = debug +sampling_rate = 512 +sentry_log_level = error diff --git a/obci/scenarios/budzik/prototypes/p300_visual_8_classes_configs/analysis.ini b/obci/scenarios/budzik/prototypes/p300_visual_8_classes_configs/analysis.ini new file mode 100644 index 00000000..985bb7a7 --- /dev/null +++ b/obci/scenarios/budzik/prototypes/p300_visual_8_classes_configs/analysis.ini @@ -0,0 +1,20 @@ + +[config_sources] + +[launch_dependencies] + +[external_params] + +[local_params] +experiment_uuid = +decision_stop = 2 +console_log_level = info +channels_for_classification = O1;O2;Pz;Cz;M1;M2 +montage_channels = M1;M2 +log_dir = ~/.obci/logs +offline_learning = 0 +mx_log_level = info +file_log_level = debug +downsample_to = 24 +sentry_log_level = error +decision_stop_threshold=0.6 diff --git a/obci/scenarios/budzik/prototypes/p300_visual_8_classes_configs/blink_catcher.ini b/obci/scenarios/budzik/prototypes/p300_visual_8_classes_configs/blink_catcher.ini new file mode 100644 index 00000000..cb6640e0 --- /dev/null +++ b/obci/scenarios/budzik/prototypes/p300_visual_8_classes_configs/blink_catcher.ini @@ -0,0 +1,14 @@ + +[config_sources] + +[launch_dependencies] + +[external_params] + +[local_params] +experiment_uuid = +console_log_level = info +log_dir = ~/.obci/logs +mx_log_level = info +file_log_level = debug +sentry_log_level = error diff --git a/obci/scenarios/budzik/prototypes/p300_visual_8_classes_configs/config_server.ini b/obci/scenarios/budzik/prototypes/p300_visual_8_classes_configs/config_server.ini new file mode 100644 index 00000000..cb6640e0 --- /dev/null +++ b/obci/scenarios/budzik/prototypes/p300_visual_8_classes_configs/config_server.ini @@ -0,0 +1,14 @@ + +[config_sources] + +[launch_dependencies] + +[external_params] + +[local_params] +experiment_uuid = +console_log_level = info +log_dir = ~/.obci/logs +mx_log_level = info +file_log_level = debug +sentry_log_level = error diff --git a/obci/scenarios/budzik/prototypes/p300_visual_8_classes_configs/feedback.ini b/obci/scenarios/budzik/prototypes/p300_visual_8_classes_configs/feedback.ini new file mode 100644 index 00000000..a26604ca --- /dev/null +++ b/obci/scenarios/budzik/prototypes/p300_visual_8_classes_configs/feedback.ini @@ -0,0 +1,15 @@ + +[config_sources] + +[launch_dependencies] + +[external_params] + +[local_params] +experiment_uuid = +console_log_level = info +hello_message = Start BCI, wysłuchaj pytania i skup się na odpowiedzi +sentry_log_level = error +mx_log_level = info +file_log_level = debug +log_dir = ~/.obci/logs diff --git a/obci/scenarios/budzik/prototypes/p300_visual_8_classes_configs/info_saver.ini b/obci/scenarios/budzik/prototypes/p300_visual_8_classes_configs/info_saver.ini new file mode 100644 index 00000000..cb6640e0 --- /dev/null +++ b/obci/scenarios/budzik/prototypes/p300_visual_8_classes_configs/info_saver.ini @@ -0,0 +1,14 @@ + +[config_sources] + +[launch_dependencies] + +[external_params] + +[local_params] +experiment_uuid = +console_log_level = info +log_dir = ~/.obci/logs +mx_log_level = info +file_log_level = debug +sentry_log_level = error diff --git a/obci/scenarios/budzik/prototypes/p300_visual_8_classes_configs/mx.ini b/obci/scenarios/budzik/prototypes/p300_visual_8_classes_configs/mx.ini new file mode 100644 index 00000000..cb6640e0 --- /dev/null +++ b/obci/scenarios/budzik/prototypes/p300_visual_8_classes_configs/mx.ini @@ -0,0 +1,14 @@ + +[config_sources] + +[launch_dependencies] + +[external_params] + +[local_params] +experiment_uuid = +console_log_level = info +log_dir = ~/.obci/logs +mx_log_level = info +file_log_level = debug +sentry_log_level = error diff --git a/obci/scenarios/budzik/prototypes/p300_visual_8_classes_configs/signal_saver.ini b/obci/scenarios/budzik/prototypes/p300_visual_8_classes_configs/signal_saver.ini new file mode 100644 index 00000000..cd1348d6 --- /dev/null +++ b/obci/scenarios/budzik/prototypes/p300_visual_8_classes_configs/signal_saver.ini @@ -0,0 +1,15 @@ + +[config_sources] + +[launch_dependencies] + +[external_params] + +[local_params] +experiment_uuid = +save_file_name = test2 +console_log_level = info +sentry_log_level = error +mx_log_level = info +file_log_level = debug +log_dir = ~/.obci/logs diff --git a/obci/scenarios/budzik/prototypes/p300_visual_8_classes_configs/tag_saver.ini b/obci/scenarios/budzik/prototypes/p300_visual_8_classes_configs/tag_saver.ini new file mode 100644 index 00000000..cb6640e0 --- /dev/null +++ b/obci/scenarios/budzik/prototypes/p300_visual_8_classes_configs/tag_saver.ini @@ -0,0 +1,14 @@ + +[config_sources] + +[launch_dependencies] + +[external_params] + +[local_params] +experiment_uuid = +console_log_level = info +log_dir = ~/.obci/logs +mx_log_level = info +file_log_level = debug +sentry_log_level = error diff --git a/obci/scenarios/budzik/prototypes/p300_visual_8_classes_configs/ugm_engine.ini b/obci/scenarios/budzik/prototypes/p300_visual_8_classes_configs/ugm_engine.ini new file mode 100644 index 00000000..5d613aa4 --- /dev/null +++ b/obci/scenarios/budzik/prototypes/p300_visual_8_classes_configs/ugm_engine.ini @@ -0,0 +1,30 @@ + +[config_sources] +logic = + +[launch_dependencies] + +[external_params] + +[local_params] +ugm_config = budzik_visual_p300_8class +blink_ugm_id_start = 1001 +experiment_uuid = +blink_ugm_key = font_color +target_image_path = obci.gui.ugm.resources.einstein.png +blink_max_break = 0.22 +modalities = visual +blink_min_break = 0.18 +blink_ugm_type = singletextimageoddball +blink_count_max = 80 +blink_ugm_value = #E42525 +running_on_start = 0 +blink_duration = 0.15 +console_log_level = info +sentry_log_level = error +mx_log_level = info +file_log_level = debug +blink_count_min = 64 +haptic_duration = 0.8 +log_dir = ~/.obci/logs +global_target_proba = 0.7 diff --git a/obci/scenarios/budzik/prototypes/p300_visual_8_classes_configs/ugm_server.ini b/obci/scenarios/budzik/prototypes/p300_visual_8_classes_configs/ugm_server.ini new file mode 100644 index 00000000..cb6640e0 --- /dev/null +++ b/obci/scenarios/budzik/prototypes/p300_visual_8_classes_configs/ugm_server.ini @@ -0,0 +1,14 @@ + +[config_sources] + +[launch_dependencies] + +[external_params] + +[local_params] +experiment_uuid = +console_log_level = info +log_dir = ~/.obci/logs +mx_log_level = info +file_log_level = debug +sentry_log_level = error diff --git a/obci/scenarios/budzik/prototypes/p300calibrate_offline.ini b/obci/scenarios/budzik/prototypes/p300calibrate_offline.ini new file mode 100644 index 00000000..855a59d8 --- /dev/null +++ b/obci/scenarios/budzik/prototypes/p300calibrate_offline.ini @@ -0,0 +1,20 @@ +[peers] +scenario_dir= +;*********************************************** +[peers.mx] +path=multiplexer-install/bin/mxcontrol + +;*********************************************** +[peers.config_server] +path=control/peer/config_server.py + +;*********************************************** +[peers.amplifier] +path=drivers/eeg/amplifier_file.py +config=scenarios/budzik/prototypes/p300_configs/p300_amplifier_offline_calibration_config.ini + +[peers.analysis] +path=interfaces/bci/p300_MD/p300_master_peer.py +config=scenarios/budzik/prototypes/p300_configs/p300_offline_calibration_config.ini +[peers.analysis.launch_dependencies] +amplifier=amplifier diff --git a/obci/scenarios/budzik/prototypes/p300calibrate_synthetic_online.ini b/obci/scenarios/budzik/prototypes/p300calibrate_synthetic_online.ini new file mode 100644 index 00000000..df3b27f3 --- /dev/null +++ b/obci/scenarios/budzik/prototypes/p300calibrate_synthetic_online.ini @@ -0,0 +1,25 @@ +[peers] +scenario_dir= +;*********************************************** +[peers.mx] +path=multiplexer-install/bin/mxcontrol + +;*********************************************** +[peers.config_server] +path=control/peer/config_server.py + +;*********************************************** +[peers.amplifier] +path=interfaces/bci/p300_MD/tests/synthetic_generator.py + +;*********************************************** +[peers.analysis] +path=interfaces/bci/p300_MD/p300_master_peer.py +config=scenarios/budzik/prototypes/p300_configs/p300_classifier_synthetic_calibration_config.ini + +[peers.analysis.config_sources] +amplifier=amplifier + +[peers.analysis.launch_dependencies] +amplifier=synthetic_generator + diff --git a/obci/scenarios/budzik/prototypes/visual_audio_image_highlight.ini b/obci/scenarios/budzik/prototypes/visual_audio_image_highlight.ini new file mode 100644 index 00000000..25ed0148 --- /dev/null +++ b/obci/scenarios/budzik/prototypes/visual_audio_image_highlight.ini @@ -0,0 +1,119 @@ +[peers] +scenario_dir = + +[peers.switch_backup] +path = interfaces/switch/backup/switch_backup_peer.py +config = scenarios/budzik/prototypes/visual_audio_image_highlight_configs/switch_backup.ini + +[peers.feedback] +path = logic/feedback/logic_decision_feedback_peer.py +config = scenarios/budzik/prototypes/visual_audio_image_highlight_configs/feedback.ini + +[peers.feedback.config_sources] +ugm_engine = ugm_engine +analysis = analysis +logic = logic + +[peers.feedback.launch_dependencies] +ugm_server = ugm_server +ugm_engine = ugm_engine +analysis = analysis +logic = logic + +[peers.tag_saver] +path = acquisition/tag_saver_peer.py +config = scenarios/budzik/prototypes/visual_audio_image_highlight_configs/tag_saver.ini + +[peers.tag_saver.config_sources] +signal_saver = signal_saver + +[peers.tag_saver.launch_dependencies] +signal_saver = signal_saver + +[peers.amplifier] +path = drivers/eeg/amplifier_virtual.py +config = scenarios/budzik/prototypes/visual_audio_image_highlight_configs/amplifier.ini + +[peers.config_server] +path = control/peer/config_server.py +config = scenarios/budzik/prototypes/visual_audio_image_highlight_configs/config_server.ini + +[peers.analysis] +path = interfaces/bci/p300_MD/p300_master_peer.py +config = scenarios/budzik/prototypes/visual_audio_image_highlight_configs/analysis.ini + +[peers.analysis.config_sources] +amplifier = amplifier +logic = logic + +[peers.analysis.launch_dependencies] +amplifier = amplifier +logic = logic + +[peers.switch] +path = drivers/switch/switch_amplifier_peer.py +config = scenarios/budzik/prototypes/visual_audio_image_highlight_configs/switch.ini + +[peers.switch.launch_dependencies] +ugm_engine = ugm_engine + +[peers.ugm_server] +path = gui/ugm/ugm_server_peer.py +config = scenarios/budzik/prototypes/visual_audio_image_highlight_configs/ugm_server.ini + +[peers.ugm_server.config_sources] +ugm_engine = ugm_engine + +[peers.ugm_server.launch_dependencies] +ugm_engine = ugm_engine + +[peers.info_saver] +path = acquisition/info_saver_peer.py +config = scenarios/budzik/prototypes/visual_audio_image_highlight_configs/info_saver.ini + +[peers.info_saver.config_sources] +signal_saver = signal_saver +amplifier = amplifier + +[peers.info_saver.launch_dependencies] +signal_saver = signal_saver +amplifier = amplifier + +[peers.logic] +path = logic/logic_maze_peer.py +config = scenarios/budzik/prototypes/visual_audio_image_highlight_configs/logic.ini + +[peers.logic.launch_dependencies] +signal_saver = signal_saver +ugm = ugm_server + +[peers.signal_saver] +path = acquisition/signal_saver_peer.py +config = scenarios/budzik/prototypes/visual_audio_image_highlight_configs/signal_saver.ini + +[peers.signal_saver.config_sources] +amplifier = amplifier + +[peers.signal_saver.launch_dependencies] +amplifier = amplifier + +[peers.ugm_engine] +path = gui/ugm/blinking/ugm_modal_blinking_engine_peer.py +config = scenarios/budzik/prototypes/visual_audio_image_highlight_configs/ugm_engine.ini + +[peers.ugm_engine.config_sources] +logic = logic + +[peers.mx] +path = multiplexer-install/bin/mxcontrol +config = scenarios/budzik/prototypes/visual_audio_image_highlight_configs/mx.ini + +[peers.blink_catcher] +path = utils/blink_catcher_peer.py + +[peers.blink_catcher.config_sources] +ugm_engine = ugm_engine + +[peers.blink_catcher.launch_dependencies] +ugm_engine = ugm_engine + diff --git a/obci/scenarios/budzik/prototypes/visual_audio_image_highlight_configs/amplifier.ini b/obci/scenarios/budzik/prototypes/visual_audio_image_highlight_configs/amplifier.ini new file mode 100644 index 00000000..2fa97c86 --- /dev/null +++ b/obci/scenarios/budzik/prototypes/visual_audio_image_highlight_configs/amplifier.ini @@ -0,0 +1,17 @@ + +[config_sources] + +[launch_dependencies] + +[external_params] + +[local_params] +active_channels = 0;1;2;3;4;5;6;7;8;Saw;Driver_Saw +channel_names = PO7;O1;Oz;O2;PO8;PO3;PO4;Pz;Cz;AmpSaw;DriverSaw +experiment_uuid = +console_log_level = info +log_dir = ~/.obci/logs +mx_log_level = info +file_log_level = debug +sampling_rate = 512 +sentry_log_level = error diff --git a/obci/scenarios/budzik/prototypes/visual_audio_image_highlight_configs/analysis.ini b/obci/scenarios/budzik/prototypes/visual_audio_image_highlight_configs/analysis.ini new file mode 100644 index 00000000..7c2e5286 --- /dev/null +++ b/obci/scenarios/budzik/prototypes/visual_audio_image_highlight_configs/analysis.ini @@ -0,0 +1,19 @@ + +[config_sources] +logic = + +[launch_dependencies] +logic = + +[external_params] + +[local_params] +experiment_uuid = +console_log_level = info +file_log_level = debug +sentry_log_level = error +offline_learning = 0 +mx_log_level = info +channels_for_classification = O1;O2;Pz;Cz +log_dir = ~/.obci/logs +downsample_to = 24 diff --git a/obci/scenarios/budzik/prototypes/visual_audio_image_highlight_configs/config_server.ini b/obci/scenarios/budzik/prototypes/visual_audio_image_highlight_configs/config_server.ini new file mode 100644 index 00000000..cb6640e0 --- /dev/null +++ b/obci/scenarios/budzik/prototypes/visual_audio_image_highlight_configs/config_server.ini @@ -0,0 +1,14 @@ + +[config_sources] + +[launch_dependencies] + +[external_params] + +[local_params] +experiment_uuid = +console_log_level = info +log_dir = ~/.obci/logs +mx_log_level = info +file_log_level = debug +sentry_log_level = error diff --git a/obci/scenarios/budzik/prototypes/visual_audio_image_highlight_configs/feedback.ini b/obci/scenarios/budzik/prototypes/visual_audio_image_highlight_configs/feedback.ini new file mode 100644 index 00000000..cb6640e0 --- /dev/null +++ b/obci/scenarios/budzik/prototypes/visual_audio_image_highlight_configs/feedback.ini @@ -0,0 +1,14 @@ + +[config_sources] + +[launch_dependencies] + +[external_params] + +[local_params] +experiment_uuid = +console_log_level = info +log_dir = ~/.obci/logs +mx_log_level = info +file_log_level = debug +sentry_log_level = error diff --git a/obci/scenarios/budzik/prototypes/visual_audio_image_highlight_configs/info_saver.ini b/obci/scenarios/budzik/prototypes/visual_audio_image_highlight_configs/info_saver.ini new file mode 100644 index 00000000..cb6640e0 --- /dev/null +++ b/obci/scenarios/budzik/prototypes/visual_audio_image_highlight_configs/info_saver.ini @@ -0,0 +1,14 @@ + +[config_sources] + +[launch_dependencies] + +[external_params] + +[local_params] +experiment_uuid = +console_log_level = info +log_dir = ~/.obci/logs +mx_log_level = info +file_log_level = debug +sentry_log_level = error diff --git a/obci/scenarios/budzik/prototypes/visual_audio_image_highlight_configs/logic.ini b/obci/scenarios/budzik/prototypes/visual_audio_image_highlight_configs/logic.ini new file mode 100644 index 00000000..02bf4bc9 --- /dev/null +++ b/obci/scenarios/budzik/prototypes/visual_audio_image_highlight_configs/logic.ini @@ -0,0 +1,19 @@ + +[config_sources] + +[launch_dependencies] +signal_saver = + +[external_params] + +[local_params] +experiment_uuid = +active_field_ids = 0;2;5 +dec_count = 3 +logic_decision_config = obci.logic.configs.config_maze_rovio.Config +robot_ip = 192.168.1.18 +console_log_level = info +sentry_log_level = error +mx_log_level = info +file_log_level = debug +log_dir = ~/.obci/logs diff --git a/obci/scenarios/budzik/prototypes/visual_audio_image_highlight_configs/mx.ini b/obci/scenarios/budzik/prototypes/visual_audio_image_highlight_configs/mx.ini new file mode 100644 index 00000000..cb6640e0 --- /dev/null +++ b/obci/scenarios/budzik/prototypes/visual_audio_image_highlight_configs/mx.ini @@ -0,0 +1,14 @@ + +[config_sources] + +[launch_dependencies] + +[external_params] + +[local_params] +experiment_uuid = +console_log_level = info +log_dir = ~/.obci/logs +mx_log_level = info +file_log_level = debug +sentry_log_level = error diff --git a/obci/scenarios/budzik/prototypes/visual_audio_image_highlight_configs/signal_saver.ini b/obci/scenarios/budzik/prototypes/visual_audio_image_highlight_configs/signal_saver.ini new file mode 100644 index 00000000..cd1348d6 --- /dev/null +++ b/obci/scenarios/budzik/prototypes/visual_audio_image_highlight_configs/signal_saver.ini @@ -0,0 +1,15 @@ + +[config_sources] + +[launch_dependencies] + +[external_params] + +[local_params] +experiment_uuid = +save_file_name = test2 +console_log_level = info +sentry_log_level = error +mx_log_level = info +file_log_level = debug +log_dir = ~/.obci/logs diff --git a/obci/scenarios/budzik/prototypes/visual_audio_image_highlight_configs/switch.ini b/obci/scenarios/budzik/prototypes/visual_audio_image_highlight_configs/switch.ini new file mode 100644 index 00000000..cb6640e0 --- /dev/null +++ b/obci/scenarios/budzik/prototypes/visual_audio_image_highlight_configs/switch.ini @@ -0,0 +1,14 @@ + +[config_sources] + +[launch_dependencies] + +[external_params] + +[local_params] +experiment_uuid = +console_log_level = info +log_dir = ~/.obci/logs +mx_log_level = info +file_log_level = debug +sentry_log_level = error diff --git a/obci/scenarios/budzik/prototypes/visual_audio_image_highlight_configs/switch_backup.ini b/obci/scenarios/budzik/prototypes/visual_audio_image_highlight_configs/switch_backup.ini new file mode 100644 index 00000000..81e49483 --- /dev/null +++ b/obci/scenarios/budzik/prototypes/visual_audio_image_highlight_configs/switch_backup.ini @@ -0,0 +1,15 @@ + +[config_sources] + +[launch_dependencies] + +[external_params] + +[local_params] +experiment_uuid = +console_log_level = info +log_dir = ~/.obci/logs +sentry_log_level = error +mx_log_level = info +file_log_level = debug +finish_saving = 1 diff --git a/obci/scenarios/budzik/prototypes/visual_audio_image_highlight_configs/tag_saver.ini b/obci/scenarios/budzik/prototypes/visual_audio_image_highlight_configs/tag_saver.ini new file mode 100644 index 00000000..cb6640e0 --- /dev/null +++ b/obci/scenarios/budzik/prototypes/visual_audio_image_highlight_configs/tag_saver.ini @@ -0,0 +1,14 @@ + +[config_sources] + +[launch_dependencies] + +[external_params] + +[local_params] +experiment_uuid = +console_log_level = info +log_dir = ~/.obci/logs +mx_log_level = info +file_log_level = debug +sentry_log_level = error diff --git a/obci/scenarios/budzik/prototypes/visual_audio_image_highlight_configs/ugm_engine.ini b/obci/scenarios/budzik/prototypes/visual_audio_image_highlight_configs/ugm_engine.ini new file mode 100644 index 00000000..b30579e3 --- /dev/null +++ b/obci/scenarios/budzik/prototypes/visual_audio_image_highlight_configs/ugm_engine.ini @@ -0,0 +1,30 @@ + +[config_sources] +logic = + +[launch_dependencies] + +[external_params] + +[local_params] +ugm_config = labyrinth_face_highlight +blink_ugm_id_start = 1001 +experiment_uuid = +blink_ugm_key = font_color +blink_count_min = 64 +blink_max_break = 1.12 +modalities = visual;auditory +blink_min_break = 1.08 +blink_count_max = 80 +blink_ugm_value = #E42525 +console_log_level = info +blink_id_count = 3 +blink_duration = 0.3 +blink_ugm_type = singletextimageoddball +sentry_log_level = error +mx_log_level = info +file_log_level = debug +active_field_ids = 0;2;5 +haptic_duration = 0.8 +blink_ugm_id_count = 3 +log_dir = ~/.obci/logs diff --git a/obci/scenarios/budzik/prototypes/visual_audio_image_highlight_configs/ugm_server.ini b/obci/scenarios/budzik/prototypes/visual_audio_image_highlight_configs/ugm_server.ini new file mode 100644 index 00000000..cb6640e0 --- /dev/null +++ b/obci/scenarios/budzik/prototypes/visual_audio_image_highlight_configs/ugm_server.ini @@ -0,0 +1,14 @@ + +[config_sources] + +[launch_dependencies] + +[external_params] + +[local_params] +experiment_uuid = +console_log_level = info +log_dir = ~/.obci/logs +mx_log_level = info +file_log_level = debug +sentry_log_level = error diff --git a/obci/scenarios/budzik/prototypes/visual_audio_no_text_image_highlight.ini b/obci/scenarios/budzik/prototypes/visual_audio_no_text_image_highlight.ini new file mode 100644 index 00000000..e307b0ed --- /dev/null +++ b/obci/scenarios/budzik/prototypes/visual_audio_no_text_image_highlight.ini @@ -0,0 +1,110 @@ +[peers] +scenario_dir = + +[peers.switch_backup] +path = interfaces/switch/backup/switch_backup_peer.py +config = scenarios/budzik/prototypes/visual_audio_no_text_image_highlight_configs/switch_backup.ini + +[peers.feedback] +path = logic/feedback/logic_decision_feedback_peer.py +config = scenarios/budzik/prototypes/visual_audio_no_text_image_highlight_configs/feedback.ini + +[peers.feedback.config_sources] +ugm_engine = ugm_engine +analysis = analysis +logic = logic + +[peers.feedback.launch_dependencies] +ugm_server = ugm_server +ugm_engine = ugm_engine +analysis = analysis +logic = logic + +[peers.tag_saver] +path = acquisition/tag_saver_peer.py +config = scenarios/budzik/prototypes/visual_audio_no_text_image_highlight_configs/tag_saver.ini + +[peers.tag_saver.config_sources] +signal_saver = signal_saver + +[peers.tag_saver.launch_dependencies] +signal_saver = signal_saver + +[peers.amplifier] +path = drivers/eeg/amplifier_virtual.py +config = scenarios/budzik/prototypes/visual_audio_no_text_image_highlight_configs/amplifier.ini + +[peers.config_server] +path = control/peer/config_server.py +config = scenarios/budzik/prototypes/visual_audio_no_text_image_highlight_configs/config_server.ini + +[peers.analysis] +path = interfaces/bci/p300_MD/p300_master_peer.py +config = scenarios/budzik/prototypes/visual_audio_no_text_image_highlight_configs/analysis.ini + +[peers.analysis.config_sources] +amplifier = amplifier +logic = logic + +[peers.analysis.launch_dependencies] +amplifier = amplifier +logic = logic + +[peers.switch] +path = drivers/switch/switch_amplifier_peer.py +config = scenarios/budzik/prototypes/visual_audio_no_text_image_highlight_configs/switch.ini + +[peers.switch.launch_dependencies] +ugm_engine = ugm_engine + +[peers.ugm_server] +path = gui/ugm/ugm_server_peer.py +config = scenarios/budzik/prototypes/visual_audio_no_text_image_highlight_configs/ugm_server.ini + +[peers.ugm_server.config_sources] +ugm_engine = ugm_engine + +[peers.ugm_server.launch_dependencies] +ugm_engine = ugm_engine + +[peers.info_saver] +path = acquisition/info_saver_peer.py +config = scenarios/budzik/prototypes/visual_audio_no_text_image_highlight_configs/info_saver.ini + +[peers.info_saver.config_sources] +signal_saver = signal_saver +amplifier = amplifier + +[peers.info_saver.launch_dependencies] +signal_saver = signal_saver +amplifier = amplifier + +[peers.logic] +path = logic/logic_maze_peer.py +config = scenarios/budzik/prototypes/visual_audio_no_text_image_highlight_configs/logic.ini + +[peers.logic.launch_dependencies] +signal_saver = signal_saver +ugm = ugm_server + +[peers.signal_saver] +path = acquisition/signal_saver_peer.py +config = scenarios/budzik/prototypes/visual_audio_no_text_image_highlight_configs/signal_saver.ini + +[peers.signal_saver.config_sources] +amplifier = amplifier + +[peers.signal_saver.launch_dependencies] +amplifier = amplifier + +[peers.ugm_engine] +path = gui/ugm/blinking/ugm_modal_blinking_engine_peer.py +config = scenarios/budzik/prototypes/visual_audio_no_text_image_highlight_configs/ugm_engine.ini + +[peers.ugm_engine.config_sources] +logic = logic + +[peers.mx] +path = multiplexer-install/bin/mxcontrol +config = scenarios/budzik/prototypes/visual_audio_no_text_image_highlight_configs/mx.ini + diff --git a/obci/scenarios/budzik/prototypes/visual_audio_no_text_image_highlight_configs/amplifier.ini b/obci/scenarios/budzik/prototypes/visual_audio_no_text_image_highlight_configs/amplifier.ini new file mode 100644 index 00000000..2fa97c86 --- /dev/null +++ b/obci/scenarios/budzik/prototypes/visual_audio_no_text_image_highlight_configs/amplifier.ini @@ -0,0 +1,17 @@ + +[config_sources] + +[launch_dependencies] + +[external_params] + +[local_params] +active_channels = 0;1;2;3;4;5;6;7;8;Saw;Driver_Saw +channel_names = PO7;O1;Oz;O2;PO8;PO3;PO4;Pz;Cz;AmpSaw;DriverSaw +experiment_uuid = +console_log_level = info +log_dir = ~/.obci/logs +mx_log_level = info +file_log_level = debug +sampling_rate = 512 +sentry_log_level = error diff --git a/obci/scenarios/budzik/prototypes/visual_audio_no_text_image_highlight_configs/analysis.ini b/obci/scenarios/budzik/prototypes/visual_audio_no_text_image_highlight_configs/analysis.ini new file mode 100644 index 00000000..7c2e5286 --- /dev/null +++ b/obci/scenarios/budzik/prototypes/visual_audio_no_text_image_highlight_configs/analysis.ini @@ -0,0 +1,19 @@ + +[config_sources] +logic = + +[launch_dependencies] +logic = + +[external_params] + +[local_params] +experiment_uuid = +console_log_level = info +file_log_level = debug +sentry_log_level = error +offline_learning = 0 +mx_log_level = info +channels_for_classification = O1;O2;Pz;Cz +log_dir = ~/.obci/logs +downsample_to = 24 diff --git a/obci/scenarios/budzik/prototypes/visual_audio_no_text_image_highlight_configs/config_server.ini b/obci/scenarios/budzik/prototypes/visual_audio_no_text_image_highlight_configs/config_server.ini new file mode 100644 index 00000000..cb6640e0 --- /dev/null +++ b/obci/scenarios/budzik/prototypes/visual_audio_no_text_image_highlight_configs/config_server.ini @@ -0,0 +1,14 @@ + +[config_sources] + +[launch_dependencies] + +[external_params] + +[local_params] +experiment_uuid = +console_log_level = info +log_dir = ~/.obci/logs +mx_log_level = info +file_log_level = debug +sentry_log_level = error diff --git a/obci/scenarios/budzik/prototypes/visual_audio_no_text_image_highlight_configs/feedback.ini b/obci/scenarios/budzik/prototypes/visual_audio_no_text_image_highlight_configs/feedback.ini new file mode 100644 index 00000000..cb6640e0 --- /dev/null +++ b/obci/scenarios/budzik/prototypes/visual_audio_no_text_image_highlight_configs/feedback.ini @@ -0,0 +1,14 @@ + +[config_sources] + +[launch_dependencies] + +[external_params] + +[local_params] +experiment_uuid = +console_log_level = info +log_dir = ~/.obci/logs +mx_log_level = info +file_log_level = debug +sentry_log_level = error diff --git a/obci/scenarios/budzik/prototypes/visual_audio_no_text_image_highlight_configs/info_saver.ini b/obci/scenarios/budzik/prototypes/visual_audio_no_text_image_highlight_configs/info_saver.ini new file mode 100644 index 00000000..cb6640e0 --- /dev/null +++ b/obci/scenarios/budzik/prototypes/visual_audio_no_text_image_highlight_configs/info_saver.ini @@ -0,0 +1,14 @@ + +[config_sources] + +[launch_dependencies] + +[external_params] + +[local_params] +experiment_uuid = +console_log_level = info +log_dir = ~/.obci/logs +mx_log_level = info +file_log_level = debug +sentry_log_level = error diff --git a/obci/scenarios/budzik/prototypes/visual_audio_no_text_image_highlight_configs/logic.ini b/obci/scenarios/budzik/prototypes/visual_audio_no_text_image_highlight_configs/logic.ini new file mode 100644 index 00000000..02bf4bc9 --- /dev/null +++ b/obci/scenarios/budzik/prototypes/visual_audio_no_text_image_highlight_configs/logic.ini @@ -0,0 +1,19 @@ + +[config_sources] + +[launch_dependencies] +signal_saver = + +[external_params] + +[local_params] +experiment_uuid = +active_field_ids = 0;2;5 +dec_count = 3 +logic_decision_config = obci.logic.configs.config_maze_rovio.Config +robot_ip = 192.168.1.18 +console_log_level = info +sentry_log_level = error +mx_log_level = info +file_log_level = debug +log_dir = ~/.obci/logs diff --git a/obci/scenarios/budzik/prototypes/visual_audio_no_text_image_highlight_configs/mx.ini b/obci/scenarios/budzik/prototypes/visual_audio_no_text_image_highlight_configs/mx.ini new file mode 100644 index 00000000..cb6640e0 --- /dev/null +++ b/obci/scenarios/budzik/prototypes/visual_audio_no_text_image_highlight_configs/mx.ini @@ -0,0 +1,14 @@ + +[config_sources] + +[launch_dependencies] + +[external_params] + +[local_params] +experiment_uuid = +console_log_level = info +log_dir = ~/.obci/logs +mx_log_level = info +file_log_level = debug +sentry_log_level = error diff --git a/obci/scenarios/budzik/prototypes/visual_audio_no_text_image_highlight_configs/signal_saver.ini b/obci/scenarios/budzik/prototypes/visual_audio_no_text_image_highlight_configs/signal_saver.ini new file mode 100644 index 00000000..cd1348d6 --- /dev/null +++ b/obci/scenarios/budzik/prototypes/visual_audio_no_text_image_highlight_configs/signal_saver.ini @@ -0,0 +1,15 @@ + +[config_sources] + +[launch_dependencies] + +[external_params] + +[local_params] +experiment_uuid = +save_file_name = test2 +console_log_level = info +sentry_log_level = error +mx_log_level = info +file_log_level = debug +log_dir = ~/.obci/logs diff --git a/obci/scenarios/budzik/prototypes/visual_audio_no_text_image_highlight_configs/switch.ini b/obci/scenarios/budzik/prototypes/visual_audio_no_text_image_highlight_configs/switch.ini new file mode 100644 index 00000000..cb6640e0 --- /dev/null +++ b/obci/scenarios/budzik/prototypes/visual_audio_no_text_image_highlight_configs/switch.ini @@ -0,0 +1,14 @@ + +[config_sources] + +[launch_dependencies] + +[external_params] + +[local_params] +experiment_uuid = +console_log_level = info +log_dir = ~/.obci/logs +mx_log_level = info +file_log_level = debug +sentry_log_level = error diff --git a/obci/scenarios/budzik/prototypes/visual_audio_no_text_image_highlight_configs/switch_backup.ini b/obci/scenarios/budzik/prototypes/visual_audio_no_text_image_highlight_configs/switch_backup.ini new file mode 100644 index 00000000..81e49483 --- /dev/null +++ b/obci/scenarios/budzik/prototypes/visual_audio_no_text_image_highlight_configs/switch_backup.ini @@ -0,0 +1,15 @@ + +[config_sources] + +[launch_dependencies] + +[external_params] + +[local_params] +experiment_uuid = +console_log_level = info +log_dir = ~/.obci/logs +sentry_log_level = error +mx_log_level = info +file_log_level = debug +finish_saving = 1 diff --git a/obci/scenarios/budzik/prototypes/visual_audio_no_text_image_highlight_configs/tag_saver.ini b/obci/scenarios/budzik/prototypes/visual_audio_no_text_image_highlight_configs/tag_saver.ini new file mode 100644 index 00000000..cb6640e0 --- /dev/null +++ b/obci/scenarios/budzik/prototypes/visual_audio_no_text_image_highlight_configs/tag_saver.ini @@ -0,0 +1,14 @@ + +[config_sources] + +[launch_dependencies] + +[external_params] + +[local_params] +experiment_uuid = +console_log_level = info +log_dir = ~/.obci/logs +mx_log_level = info +file_log_level = debug +sentry_log_level = error diff --git a/obci/scenarios/budzik/prototypes/visual_audio_no_text_image_highlight_configs/ugm_engine.ini b/obci/scenarios/budzik/prototypes/visual_audio_no_text_image_highlight_configs/ugm_engine.ini new file mode 100644 index 00000000..09ad4e32 --- /dev/null +++ b/obci/scenarios/budzik/prototypes/visual_audio_no_text_image_highlight_configs/ugm_engine.ini @@ -0,0 +1,32 @@ + +[config_sources] +logic = + +[launch_dependencies] + +[external_params] + +[local_params] +ugm_config = labyrinth_face_highlight +blink_ugm_id_start = 2001 +images_path = ~/dataset/pictures +modalities = visual;auditory +images_extension = png +blink_ugm_key = font_color +haptic_duration = 0.8 +sentry_log_level = error +blink_ugm_value = #E42525 +log_dir = ~/.obci/logs +blink_duration = 0.3 +blink_count_min = 64 +blink_count_max = 80 +mx_log_level = info +console_log_level = info +file_log_level = debug +experiment_uuid = +active_field_ids = 0;2;5 +blink_max_break = 1.12 +blink_min_break = 1.08 +blink_id_count = 3 +blink_ugm_id_count = 3 +blink_ugm_type = singleimageoddball diff --git a/obci/scenarios/budzik/prototypes/visual_audio_no_text_image_highlight_configs/ugm_server.ini b/obci/scenarios/budzik/prototypes/visual_audio_no_text_image_highlight_configs/ugm_server.ini new file mode 100644 index 00000000..cb6640e0 --- /dev/null +++ b/obci/scenarios/budzik/prototypes/visual_audio_no_text_image_highlight_configs/ugm_server.ini @@ -0,0 +1,14 @@ + +[config_sources] + +[launch_dependencies] + +[external_params] + +[local_params] +experiment_uuid = +console_log_level = info +log_dir = ~/.obci/logs +mx_log_level = info +file_log_level = debug +sentry_log_level = error