Exemplo n.º 1
0
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()))
Exemplo n.º 2
0
    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"))
Exemplo n.º 3
0
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")
Exemplo n.º 4
0
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()))
Exemplo n.º 5
0
    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.")
Exemplo n.º 6
0
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()))
Exemplo n.º 7
0
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)
Exemplo n.º 8
0
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
Exemplo n.º 9
0
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()))
Exemplo n.º 10
0
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()))