def _setup(): '''Initialize the module This adds a set of global variables ''' global parser, args, config, r, response, patch parser = argparse.ArgumentParser() parser.add_argument("-i", "--inifile", default=os.path.join(path, name + '.ini'), help="name of the configuration file") args = parser.parse_args() config = configparser.ConfigParser(inline_comment_prefixes=('#', ';')) config.read(args.inifile) try: r = redis.StrictRedis(host=config.get('redis', 'hostname'), port=config.getint('redis', 'port'), db=0, charset='utf-8', decode_responses=True) response = r.client_list() except redis.ConnectionError: raise RuntimeError("cannot connect to Redis server") # combine the patching from the configuration file and Redis patch = EEGsynth.patch(config, r) # there should not be any local variables in this function, they should all be global if len(locals()): print('LOCALS: ' + ', '.join(locals().keys()))
def __init__(self, path, name): # Configuration. parser = argparse.ArgumentParser() parser.add_argument("-i", "--inifile", default=os.path.join(path, name + '.ini'), help="name of the configuration file") args = parser.parse_args() config = configparser.ConfigParser(inline_comment_prefixes=('#', ';')) config.read(args.inifile) # Redis. try: rds = redis.StrictRedis(host=config.get('redis', 'hostname'), port=config.getint('redis', 'port'), db=0, charset='utf-8', decode_responses=True) except redis.ConnectionError as e: raise RuntimeError(e) # Combine the patching from the configuration file and Redis. self.patch = EEGsynth.patch(config, rds) # BLE client. self.loop = asyncio.get_event_loop() self.ble_client = BleakClient(self.patch.getstring("input", "mac"), loop=self.loop) self.monitor = EEGsynth.monitor(name=name, debug=self.patch.getint( "general", "debug"))
def _setup(): '''Initialize the module This adds a set of global variables ''' global parser, args, config, r, response, patch, monitor, ft_host, ft_port, ft_input parser = argparse.ArgumentParser() parser.add_argument("-i", "--inifile", default=os.path.join(path, name + '.ini'), help="name of the configuration file") args = parser.parse_args() config = configparser.ConfigParser(inline_comment_prefixes=('#', ';')) config.read(args.inifile) try: r = redis.StrictRedis(host=config.get('redis', 'hostname'), port=config.getint('redis', 'port'), db=0, charset='utf-8', decode_responses=True) response = r.client_list() except redis.ConnectionError: raise RuntimeError("cannot connect to Redis server") # combine the patching from the configuration file and Redis patch = EEGsynth.patch(config, r) # this can be used to show parameters that have changed monitor = EEGsynth.monitor(name=name, debug=patch.getint('general', 'debug')) try: ft_host = patch.getstring('fieldtrip', 'hostname') ft_port = patch.getint('fieldtrip', 'port') monitor.info('Trying to connect to buffer on %s:%i ...' % (ft_host, ft_port)) ft_input = FieldTrip.Client() ft_input.connect(ft_host, ft_port) monitor.info("Connected to input FieldTrip buffer") except: raise RuntimeError("cannot connect to input FieldTrip buffer")
def _start(): '''Start the module This uses the global variables from setup and adds a set of global variables ''' global parser, args, config, r, response global patch, monitor, debug, inputlist, enable, stepsize, window, numchannel, numhistory, history, historic, metrics_iqr, metrics_mad, metrics_max, metrics_max_att, metrics_mean, metrics_median, metrics_min, metrics_min_att, metrics_p03, metrics_p16, metrics_p84, metrics_p97, metrics_range, metrics_std # combine the patching from the configuration file and Redis patch = EEGsynth.patch(config, r) # this can be used to show parameters that have changed monitor = EEGsynth.monitor(name=name, debug=patch.getint('general', 'debug')) # get the options from the configuration file debug = patch.getint('general', 'debug') inputlist = patch.getstring('input', 'channels', multiple=True) enable = patch.getint('history', 'enable', default=1) stepsize = patch.getfloat('history', 'stepsize') # in seconds window = patch.getfloat('history', 'window') # in seconds metrics_iqr = patch.getint('metrics', 'iqr', default=1) != 0 metrics_mad = patch.getint('metrics', 'mad', default=1) != 0 metrics_max = patch.getint('metrics', 'max', default=1) != 0 metrics_max_att = patch.getint('metrics', 'max_att', default=1) != 0 metrics_mean = patch.getint('metrics', 'mean', default=1) != 0 metrics_median = patch.getint('metrics', 'median', default=1) != 0 metrics_min = patch.getint('metrics', 'min', default=1) != 0 metrics_min_att = patch.getint('metrics', 'min_att', default=1) != 0 metrics_p03 = patch.getint('metrics', 'p03', default=1) != 0 metrics_p16 = patch.getint('metrics', 'p16', default=1) != 0 metrics_p84 = patch.getint('metrics', 'p84', default=1) != 0 metrics_p97 = patch.getint('metrics', 'p97', default=1) != 0 metrics_range = patch.getint('metrics', 'range', default=1) != 0 metrics_std = patch.getint('metrics', 'std', default=1) != 0 numchannel = len(inputlist) numhistory = int(round(window / stepsize)) # this will contain the full list of historic values history = np.empty((numchannel, numhistory)) * np.NAN # this will contain the statistics of the historic values historic = {} # there should not be any local variables in this function, they should all be global if len(locals()): print('LOCALS: ' + ', '.join(locals().keys()))
def __init__(self, path, name): # Configuration. parser = argparse.ArgumentParser() parser.add_argument("-i", "--inifile", default=os.path.join(path, name + '.ini'), help="name of the configuration file") args = parser.parse_args() config = configparser.ConfigParser(inline_comment_prefixes=('#', ';')) config.read(args.inifile) # Redis. try: rds = redis.StrictRedis(host=config.get('redis', 'hostname'), port=config.getint('redis', 'port'), db=0, charset='utf-8', decode_responses=True) except redis.ConnectionError as e: raise RuntimeError(e) self.patch = EEGsynth.patch( config, rds) # combine patching from configuration file and Redis. # Monitor. self.monitor = EEGsynth.monitor(name=name, debug=self.patch.getint( 'general', 'debug')) # FieldTrip. try: ft_host = self.patch.getstring('fieldtrip', 'hostname') ft_port = self.patch.getint('fieldtrip', 'port') self.monitor.success( "Trying to connect to buffer on {0}{1}.".format( ft_host, ft_port)) self.ft_input = FieldTrip.Client() self.ft_input.connect(ft_host, ft_port) self.monitor.success('Connected to input FieldTrip buffer.') except: raise RuntimeError("Cannot connect to input FieldTrip buffer.")
def _start(): '''Start the module This uses the global variables from setup and adds a set of global variables ''' global parser, args, config, r, response global patch, monitor, debug, channels, multipliers, lrate, count, triggers, channel, multiplier, thread # combine the patching from the configuration file and Redis patch = EEGsynth.patch(config, r) # this can be used to show parameters that have changed monitor = EEGsynth.monitor(name=name, debug=patch.getint('general', 'debug')) # get the options from the configuration file debug = patch.getint('general', 'debug') channels = patch.getstring('clock', 'channel', multiple=True) multipliers = patch.getint('clock', 'rate', multiple=True) lrate = patch.getfloat('clock', 'learning_rate', default=1) # for keeping track of the number of received triggers count = 0 triggers = [] for channel in channels: for multiplier in multipliers: triggers.append(TriggerThread(channel, multiplier, lrate)) monitor.debug("x%d.%s" % (multiplier, channel)) # start the thread for each of the triggers for thread in triggers: thread.start() # there should not be any local variables in this function, they should all be global if len(locals()): print('LOCALS: ' + ', '.join(locals().keys()))
parser = argparse.ArgumentParser() parser.add_argument("-i", "--inifile", default=os.path.join(installed_folder, os.path.splitext(os.path.basename(__file__))[0] + '.ini'), help="optional name of the configuration file") args = parser.parse_args() config = ConfigParser.ConfigParser() config.read(args.inifile) try: r = redis.StrictRedis(host=config.get('redis','hostname'), port=config.getint('redis','port'), db=0) response = r.client_list() except redis.ConnectionError: print "Error: cannot connect to redis server" exit() # combine the patching from the configuration file and Redis patch = EEGsynth.patch(config, r) del config # this determines how much debugging information gets printed debug = patch.getint('general','debug') def butter_bandpass(lowcut, highcut, fs, order=9): nyq = 0.5 * fs low = lowcut / nyq high = highcut / nyq b, a = butter(order, [low, high], btype='band') return b, a def butter_bandpass_filter(data, lowcut, highcut, fs, order=9): b, a = butter_bandpass(lowcut, highcut, fs, order=order) y = lfilter(b, a, data)
parser = argparse.ArgumentParser() parser.add_argument("-i", "--inifile", default=os.path.join(installed_folder, os.path.splitext(os.path.basename(__file__))[0] + '.ini'), help="optional name of the configuration file") args = parser.parse_args() config = configparser.ConfigParser(inline_comment_prefixes=('#', ';')) config.read(args.inifile) try: r = redis.StrictRedis(host=config.get('redis', 'hostname'), port=config.getint('redis', 'port'), db=0) response = r.client_list() except redis.ConnectionError: print("Error: cannot connect to redis server") exit() # combine the patching from the configuration file and Redis patch = EEGsynth.patch(config, r) # this determines how much debugging information gets printed debug = patch.getint('general', 'debug') # keep track of the number of received triggers count = 0 class TriggerThread(threading.Thread): def __init__(self, redischannel, rate): threading.Thread.__init__(self) self.redischannel = redischannel self.rate = rate self.key = "d%d.%s" % (rate, redischannel) self.count = 0 self.running = True
def _start(): '''Start the module This uses the global variables from setup and adds a set of global variables ''' global parser, args, config, r, response, patch, name global monitor, debug, s, list_input, list_output, list1, list2, list3, i, j, lock, trigger, key1, key2, key3, this, thread # combine the patching from the configuration file and Redis patch = EEGsynth.patch(config, r) # this can be used to show parameters that have changed monitor = EEGsynth.monitor(name=name, debug=patch.getint('general', 'debug')) # get the options from the configuration file debug = patch.getint('general', 'debug') try: if sys.version_info < (3, 6): s = OSC.OSCClient() s.connect( (patch.getstring('osc', 'hostname'), patch.getint('osc', 'port'))) else: s = udp_client.SimpleUDPClient(patch.getstring('osc', 'hostname'), patch.getint('osc', 'port')) monitor.success('Connected to OSC server') except: raise RuntimeError("cannot connect to OSC server") # keys should be present in both the input and output section of the *.ini file list_input = config.items('input') list_output = config.items('output') list1 = [ ] # the key name that matches in the input and output section of the *.ini file list2 = [] # the key name in Redis list3 = [] # the key name in OSC for i in range(len(list_input)): for j in range(len(list_output)): if list_input[i][0] == list_output[j][0]: list1.append(list_input[i][0]) # short name in the ini file list2.append(list_input[i][1]) # redis channel list3.append(list_output[j][1]) # osc topic # this is to prevent two messages from being sent at the same time lock = threading.Lock() # each of the Redis messages is mapped onto a different OSC topic trigger = [] for key1, key2, key3 in zip(list1, list2, list3): this = TriggerThread(key2, key1, key3) trigger.append(this) monitor.debug('trigger configured for ' + key1) # start the thread for each of the triggers for thread in trigger: thread.start() # there should not be any local variables in this function, they should all be global if len(locals()): print('LOCALS: ' + ', '.join(locals().keys()))
def _start(): '''Start the module This uses the global variables from setup and adds a set of global variables ''' global parser, args, config, r, response global patch, monitor, push, toggle1, toggle2, toggle3, toggle4, slap, scale_note, scale_control, offset_note, offset_control, mididevice_input, mididevice_output, port, inputport, Off, Red_Low, Red_Full, Amber_Low, Amber_Full, Yellow_Full, Green_Low, Green_Full, ledcolor, note_list, status_list, note, state0change, state0color, state0value, state1change, state1color, state1value, state2change, state2color, state2value, state3change, state3color, state3value, state4change, state4color, state4value, state5change, state5color, state5value, midichannel, outputport # combine the patching from the command-line options, the configuration file and Redis patch = EEGsynth.patch(config, r) # this can be used to show parameters that have changed monitor = EEGsynth.monitor(name=name, debug=patch.getint('general', 'debug')) # get the options from the configuration file push = patch.getint('button', 'push', multiple=True) # push-release button toggle1 = patch.getint('button', 'toggle1', multiple=True) # on-off button toggle2 = patch.getint('button', 'toggle2', multiple=True) # on1-on2-off button toggle3 = patch.getint('button', 'toggle3', multiple=True) # on1-on2-on3-off button toggle4 = patch.getint('button', 'toggle4', multiple=True) # on1-on2-on3-on4-off button slap = patch.getint('button', 'slap', multiple=True) # slap button midichannel = patch.getint('midi', 'channel', default=None) # the scale and offset are used to map MIDI values to Redis values scale_note = patch.getfloat('scale', 'note', default=1./127) scale_control = patch.getfloat('scale', 'control', default=1./127) offset_note = patch.getfloat('offset', 'note', default=0) offset_control = patch.getfloat('offset', 'control', default=0) # on windows the input and output are different, on unix they are the same # use "input/output" when specified, otherwise use "device" for both try: mididevice_input = patch.getstring('midi', 'input') mididevice_input = EEGsynth.trimquotes(mididevice_input) except: mididevice_input = patch.getstring('midi', 'device') # fallback mididevice_input = EEGsynth.trimquotes(mididevice_input) try: mididevice_output = patch.getstring('midi', 'output') mididevice_output = EEGsynth.trimquotes(mididevice_output) except: mididevice_output = patch.getstring('midi', 'device') # fallback mididevice_output = EEGsynth.trimquotes(mididevice_output) mididevice_input = process.extractOne(mididevice_input, mido.get_input_names())[0] # select the closest match mididevice_output = process.extractOne(mididevice_output, mido.get_output_names())[0] # select the closest match # this is only for debugging, check which MIDI devices are accessible monitor.info('------ INPUT ------') for port in mido.get_input_names(): monitor.info(port) monitor.info('------ OUTPUT ------') for port in mido.get_output_names(): monitor.info(port) monitor.info('-------------------------') try: inputport = mido.open_input(mididevice_input) monitor.info("Connected to MIDI input") except: raise RuntimeError("cannot connect to MIDI input") try: outputport = mido.open_output(mididevice_output) monitor.info("Connected to MIDI output") except: raise RuntimeError("cannot connect to MIDI output") # channel 1-16 in the ini file should be mapped to 0-15 if not midichannel is None: midichannel-=1 monitor.update('midichannel', midichannel) # these are the MIDI values for the LED color Off = 12 Red_Low = 13 Red_Full = 15 Amber_Low = 29 Amber_Full = 63 Yellow_Full = 62 Green_Low = 28 Green_Full = 60 # concatenate all buttons note_list = push + toggle1 + toggle2 + toggle3 + toggle4 + slap status_list = [0] * len(note_list) # ensure that all buttons and published messages start in the Off state for note in note_list: ledcolor(note, Off) # the button handling is implemented using an internal representation and state changes # whenever the actual button is pressed or released # push button sequence P-R results in state change 0-1-0 # toggle1 button sequence P-R-P-R results in state change 0-11-12-13-0 # toggle2 button sequence P-R-P-R-P-R results in state change 0-21-22-23-24-25-0 # toggle3 button sequence P-R-P-R-P-R-P-R results in state change 0-31-32-33-34-35-36-37-0 # toggle4 button sequence P-R-P-R-P-R-P-R-P-R results in state change 0-41-42-43-44-45-46-47-48-49-0 # slap button sequence P-R results in state change 0-51-0 state0change = {0:1, 1:0} state0color = {0:Off, 1:Red_Full} state0value = {0:0, 1:127} state1change = {0:11, 11:12, 12:13, 13:0} state1color = {0:Off, 11:Red_Full} # don't change color on 12,13 state1value = {0:0, 11:127} # don't send message on 12,13 state2change = {0:21, 21:22, 22:23, 23:24, 24:25, 25:0} state2color = {0:Off, 21:Red_Full, 23:Yellow_Full} # don't change color on 22,24,25 state2value = {0:0, 21:int(127*1/2), 23:int(127*2/2)} # don't send message on 22,24,25 state3change = {0:31, 31:32, 32:33, 33:34, 34:35, 35:36, 36:37, 37:0} state3color = {0:Off, 31:Red_Full, 33:Yellow_Full, 35:Green_Full} state3value = {0:0, 31:int(127*1/3), 33:int(127*2/3), 35:int(127*3/3)} state4change = {0:41, 41:42, 42:43, 43:44, 44:45, 45:46, 46:47, 47:48, 48:49, 49:0} state4color = {0:Off, 41:Red_Full, 43:Yellow_Full, 45:Green_Full, 47:Amber_Full} state4value = {0:0, 41:int(127*1/4), 43:int(127*2/4), 45:int(127*3/4), 47:int(127*4/4)} state5change = {0:1, 1:0} state5color = {0:Off, 1:Amber_Full} state5value = {0:None, 1:127} # don't send message on button release # there should not be any local variables in this function, they should all be global if len(locals()): print('LOCALS: ' + ', '.join(locals().keys()))