obci.drivers.eeg package

Submodules

obci.drivers.eeg.amplifier_file module

class obci.drivers.eeg.amplifier_file.AmplifierFile(addresses)[source]

Bases: obci.drivers.eeg.binary_driver_wrapper.BinaryDriverWrapper

do_sampling()[source]
get_run_args(multiplexer_address)[source]
got_trigger(ts)[source]

Got trigger from the drivers. Let`s send next tag (or other message) with ts as its realtime timestamp

set_driver_params()[source]
set_tags()[source]
store_driver_description(driver_output)[source]

obci.drivers.eeg.amplifier_virtual module

class obci.drivers.eeg.amplifier_virtual.AmplifierVirtual(addresses)[source]

Bases: obci.drivers.eeg.binary_driver_wrapper.BinaryDriverWrapper

get_run_args(multiplexer_address)[source]

obci.drivers.eeg.binary_driver_wrapper module

class obci.drivers.eeg.binary_driver_wrapper.BinaryDriverWrapper(addresses, type)[source]

Bases: obci.control.peer.configured_multiplexer_server.ConfiguredMultiplexerServer, obci.drivers.eeg.driver_comm.DriverComm

A wrapper around c++ amplifier binaries with INI configuration support.

Do: 1) run super constructor to receive configs 2) run DriverComm constructor that fires binary driver 3) get json description from the driver (desc_params are required) 4) store that description in self.configs to share it with other modules 5) if autostart is set to true: 6) set driver params from config (sampling_rate and active_channels) 7) start sampling

abort(error_msg)[source]
desc_params = {'physical_channels_no': 'physical_channels', 'sampling_rates': 'sampling_rates', 'amplifier_name': 'name', 'channels_info': 'channels'}
handle_message(mxmsg)[source]
store_driver_description(driver_output)[source]
validate_params(params, amp_params_received=False)[source]

obci.drivers.eeg.driver_comm module

class obci.drivers.eeg.driver_comm.DriverComm(peer_config, mx_addresses=[('localhost', 41921)], catch_signals=True, context={'logger': <logging.Logger object>})[source]

Bases: object

Start, stop and communicate with amplifier driver binaries. Note: To run amplifier as OBCI experiment peer, use subclasses of BinaryDriverWrapper which fully support INI file configuration.

Example: >>> from obci.control.peer.peer_config import PeerConfig >>> import json

>>> conf = PeerConfig('amplifier')
>>> conf.add_local_param('driver_executable', 'dummy_amplifier')
>>> conf.add_local_param('samples_per_packet', '4')
>>> driv = DriverComm(conf)
dummy_amplifier
>>> descr = driv.get_driver_description() # channels_info
>>> dic = json.loads(descr)
>>> driv.start_sampling()
start OK

>>> time.sleep(3)
>>> driv.terminate_driver()

peer_config - parameter provider. Should respond to get_param(param_name, value) and has_param(param_name) calls. PeerConfig and PeerControl objects are suitable. mx_addresses - list of (host, port) pairs. Port value None means using default amplifier binary value.

abort(error_msg)[source]
do_sampling()[source]
do_samplingg()[source]
driver_is_running()[source]
get_driver_description()[source]
get_run_args(multiplexer_address)[source]
run_driver(run_args)[source]
set_active_channels(active_channels)[source]
set_driver_params()[source]
set_sampling_rate(sampling_rate)[source]
signal_handler()[source]
start_sampling()[source]
stop_sampling(_1=None, _2=None)[source]
terminate_driver()[source]
obci.drivers.eeg.driver_comm.enqueue_output(out, queue)[source]

obci.drivers.eeg.tags_to_mxmsg module

class obci.drivers.eeg.tags_to_mxmsg.BlinkMsg(index_lambda=<function BlinkMsg.<lambda>>)[source]

Bases: object

get_message(tag, ts, mx=True)[source]
class obci.drivers.eeg.tags_to_mxmsg.DummyMsg[source]

Bases: object

get_message(tag, ts)[source]
class obci.drivers.eeg.tags_to_mxmsg.TagMsg[source]

Bases: object

get_message(tag, ts, mx=True)[source]
class obci.drivers.eeg.tags_to_mxmsg.TagsToMxmsg(tags, handle_rules)[source]

Bases: object

For every tag in tags find its corresponding handler

next_message(ts, mx=True)[source]
obci.drivers.eeg.tags_to_mxmsg.run_test()[source]
>>> tags = [{'name':'blink', 'desc':{'blink':1}}, {'name':'not-blink', 'desc':{'blink_id':2}}, {'name':'blink',     'desc':{'blink':11}}, {'name':'not-blink', 'desc':{'blink_id':22}}, {'name':'dupa', 'start_timestamp':1,      'end_timestamp':1.5, 'channels':'', 'desc': {}}]
>>> rules = str([('blink', 'BlinkMsg()'), ('lambda t: "blink_id" in t["desc"]','BlinkMsg(lambda t: int(t["desc"]["blink_id"]))'), ('lambda t: True', 'TagMsg()')])
>>> mgr = TagsToMxmsg(tags, rules)
>>> mgr.next_message(10.0, False)[1].index
1
>>> mgr.next_message(20.0, False)[1].index
2
>>> mgr.next_message(30.0, False)[1].index
11
>>> mgr.next_message(40.0, False)[1].index
22
>>> # because gets new start_timestamp=50.0, has 0.5 len, so end_timestamp is 50.5
>>> mgr.next_message(50.0, False)[1]['end_timestamp']
50.5
>>> mgr.next_message(40.0, False)[1]
>>> rules = str([('lambda t: "blink_id" in t["desc"]', 'BlinkMsg(lambda t: int(t["desc"]["blink_id"]))')])
>>> mgr = TagsToMxmsg(tags, rules)
>>> mgr.next_message(10.0, False)[1].index
2
>>> mgr.next_message(20.0, False)[1].index
22
>>> mgr.next_message(30.0, False)[1]
>>>

obci.drivers.eeg.tmsi module

class obci.drivers.eeg.tmsi.Acknowledge[source]

Bases: obci.drivers.eeg.tmsi.Packet

Represents acknowledge packet.

ERRORS = {1: 'unknown or not implemented blocktype', 2: 'CRC error in received block', 3: "error in command data (can't do that)", 4: 'wrong blocksize (too large)', 17: 'No external power supplied', 18: 'Not possible because the Front is recording', 19: 'Storage medium is busy', 20: 'Flash memory not present', 21: 'nr of words to read from flash memory out of range', 22: 'flash memory is write protected', 23: 'incorrect value for initial inflation pressure', 24: 'wrong size or values in BP cycle list', 25: 'sample frequency divider out of range (<0, >max)', 26: 'wrong nr of user channels (<=0, >maxUSRchan)', 27: 'adress flash memory out of range', 28: 'Erasing not possible because battery low'}
get_error()[source]

Get error string.

Return type:string or None
Returns:None if there is no error. Some error text (one from values from ERROR dictionary) in the opposite case.
get_error_code()[source]

Get error code.

Return type:number
Returns:error code
is_error()[source]

Check if there is an error. Use get_error method to get error text.

Return type:bool
Returns:True iff there is an error
class obci.drivers.eeg.tmsi.ChannelData[source]

Bases: obci.drivers.eeg.tmsi.Packet

Packet containing channel data NOT encoded using VL Delta compression.

BATTERY_LOW = 64
ON_OFF_BUTTON = 1
OVERFLOW = 8388608
TRIGGER_ACTIVE = 4
battery_low()[source]

Check if battery is low.

Return type:bool
Returns:True iff battery is low.
check_digi(condition)[source]

Check if flag condition is set in digi channel.

Parameters:condition (number) – Bit flag representing some state. Valid flags are: ON_OFF_BUTTON, TRIGGER_ACTIVE, BATTERY_LOW.
Return type:bool
Returns:True iff condition is set in digi channel.
decode()[source]

Decode channel data contained in this packet.

Return type:list of lists of ints
Returns:List indexed by channel numbers. Every list contains list of values in this channel.
extract_channel_data(channel_number)[source]

Extract data of single channel.

Parameters:channel_number (number) – number of channel we want to extract data from
Return type:number
Returns:value of channel_number-th channel data
get_digi()[source]

Get Digi channel status. This channel contains data such as battery level, on off button status, trigger status.

Return type:number
Returns:byte containing flags (on/off button etc.) set in packet
on_off_pressed()[source]

Check if on/off button is pressed.

Return type:bool
Returns:True iff on/off button is pressed.
set_number_of_channels(number_of_channels)[source]

Set number of channels (obtainted from FrontendInfo).

Parameters:number_of_channels (number) – number of channels (from FrontendInfo)
trigger_active()[source]

Check if trigger is active.

Return type:bool
Returns:True iff trigger is active.
class obci.drivers.eeg.tmsi.FrontendInfo[source]

Bases: obci.drivers.eeg.tmsi.Packet

Represents FrontendInfo packet.

BASE_SAMPLE_RATE_INDEX = 13
CURRENT_SAMPLE_RATE_INDEX = 1
MAX_DIVIDER = 4
MODE_INDEX = 2
MODE_STOP = 1
MODE_STREAM = 0
NUMBER_OF_CHANNELS_INDEX = 12
NUMBER_OF_HELP_CHANNELS = 2
get_base_sample_rate()[source]

Extract base sample rate frequency from FrontendInfo packet.

Return type:number
Returns:base sample frequency of amplifier
get_number_of_data_channels()[source]

Extract number of channels from FrontendInfo packet.

Return type:number
Returns:number of hardware channels in amplifier
modify_sample_rate(frequency)[source]

Set sample frequency in (obtained from device) FrontendInfo packet.

Parameters:frequency (number) – frequency to be set to
start()[source]

Modify FrontendInfo packet to enable data streaming.

stop()[source]

Modify FrontendInfo packet to disable streaming.

class obci.drivers.eeg.tmsi.Header[source]

Bases: object

Header of data block. Does not support packets longer than 254 words (such packets) have variable header length.

TMSi protocol header is in format: - 2 start bytes: ªª - length byte: number of words in packet - 1 byte: type of packet

HEADER_SIZE = 4

size of a header in bytes

HEADER_START = 'ªª'

magic string starting header

LENGTH_OFFSET = 2

byte offset in header of packet length indicator

MAX_PACKET_LENGTH = 254

maximal supported packet length

TYPE_OFFSET = 3

byte offset in header of packet type indicator

classmethod construct(packet_type, length)[source]

Construct packet header based on packet type and packet length. Set raw representation of header based on given parameters. Validate given packet type against list of all supported packet types.

Parameters:
  • packet_type (number (one of PACKET_TYPE constants)) – type of a packet for which we are creating header
  • length (number) – length of a packet (in bytes)
Return type:

Header

Returns:

new Header instance.

classmethod read_one(stream, search=False)[source]

Reads one header from stream and returns new Header instance. If search options is present then search for header start in the stream by dropping “bad” characters.

Parameters:
  • stream (object with read(int) method (some file or stream)) – Stream containing header data.
  • search (bool) – True iff bytes not starting header should be dropped from the beginning of the stream.
Return type:

Header

Returns:

new Header instance.

class obci.drivers.eeg.tmsi.Packet[source]

Bases: object

Wire packet base class.

This class is the base of all packet classes. It provides common options related functionaility.

TMSi protocol packet is in format: - 4 byte header: if packet is shorter than 254 words (other are unsupported) - packet data - 2 byte checksum

CHECKSUM_SIZE = 2

size of a checksum field

check_type()[source]

Check if packet has packet type coherent with declared packet type (if any).

classmethod construct(packet_type, data='')[source]

Construct packet based on packet type and packet data. Calculate checksum of a packet.

Parameters:
  • packet_type (number (one of PACKET_TYPE constants)) – type of a packet for which we are creating header
  • length – data inside a packet
Return type:

Packet

Returns:

new Packet instance.

get_raw()[source]

Get raw packet data. Serialize packet.

Return type:string
Returns:raw representation of packet (header, data, checksum)
get_word(index)[source]

Get number represented by index-th word of packet.

Parameters:index (number) – index of word (in word-size units)
Return type:number
Returns:value represented by index-th word of packet
classmethod read_one(stream, search=False)[source]

Reads one data packet from stream and returns Packet instance.

Parameters:
  • stream (object with read(int) method (some file or stream)) – Stream containing packet (including header and checksum)
  • search (bool) – True iff bytes not starting header should be dropped from the beginning of the stream.
Return type:

Packet

Returns:

new Packet instance.

recalculate_checksum()[source]

Updates checksum of a packet after some changes.

set_word(index, value)[source]

Set a word in packet.

Parameters:
  • index (number) – index of word (in word-size units)
  • value (number) – value to be put into index-th word of packet
class obci.drivers.eeg.tmsi.PacketType[source]

Bases: object

This class names all suported packet types.

Generates all_known_types, names, values.

TMS_ACKNOWLEDGE = 0
TMS_CHANNEL_DATA = 1
TMS_FRONTEND_INFO = 2
TMS_FRONTEND_INFO_REQUEST = 3
TMS_KEEP_ALIVE = 39
TMS_VL_DELTA_DATA = 47
TMS_VL_DELTA_INFO = 49
TMS_VL_DELTA_INFO_REQUEST = 48
all_known_types = [0, 1, 2, 3, 39, 47, 49, 48]

list of all known types, dynamically generated

generate_internals()[source]

Generate internal fields: all_known_types, names, values

names = {'TMS_ACKNOWLEDGE': 0, 'TMS_FRONTEND_INFO_REQUEST': 3, 'TMS_FRONTEND_INFO': 2, 'TMS_VL_DELTA_INFO': 49, 'TMS_CHANNEL_DATA': 1, 'TMS_VL_DELTA_INFO_REQUEST': 48, 'TMS_KEEP_ALIVE': 39, 'TMS_VL_DELTA_DATA': 47}

dict of name => value, dynamically generated

print_types()[source]

Show all available packet types.

values = {0: 'TMS_ACKNOWLEDGE', 1: 'TMS_CHANNEL_DATA', 2: 'TMS_FRONTEND_INFO', 3: 'TMS_FRONTEND_INFO_REQUEST', 48: 'TMS_VL_DELTA_INFO_REQUEST', 49: 'TMS_VL_DELTA_INFO', 39: 'TMS_KEEP_ALIVE', 47: 'TMS_VL_DELTA_DATA'}

dict of value => name, dynamically generated

class obci.drivers.eeg.tmsi.VLDeltaData[source]

Bases: obci.drivers.eeg.tmsi.ChannelData

Packet containing VL Delta channel data. Supports VL Delta compression.

Delta dat packet has the following format:

  • header
  • references: data in all channels at the beginning of quant of time, including data for digi and saw channels, these values are encoded like in normal ChannelData packet
  • delta bits: see below
  • filling (because delta bits len can not be divisible by 16bit = word size)
  • checksum

Delta bits is raw stream of bits. Every delta is encoded as 4 bit length + delta body. Delta length can name values from 0 to 15. If length is 0, then delta body has 2 bits! In opposit case, delta body has delta length bits. Delta length 0 (so in length we have all 0bits: “0000” bits) is used to encode special delta values:

  • 0 - delta = 0
  • 1 - this value is never used!
  • 2 - channels is in overflow
  • 3 - delta = -1

Every channel can have different divider. Lets consider an example, where there are only two channels: A and B. Channel A is send with 128Hz freq. Channel B is send with 256Hz freq. Base frequency is set to 64Hz. Then in 1/64s we have 2 data in A and 4 data in B. So the VLDelta packet will consist of reference samples: 1 for A and 1 for B. Then it will multiplex: delta for channel B, delta for channel A, delta for channel B, delta for channel B. If some channel was in overflow at the beginning of quant of time then it is not included later in deltas (till the end of this packet). If some channel become in overflow in the middle of the packet, this is signalised by using special delta, and later this channel will not be send in deltas (till the end of this packet).

decode()[source]

Decode channel data contained in this packet. Supports VL Delta compression.

Return type:list of lists of ints
Returns:List indexed by channel numbers. Every list contains list of values in this channel.
decode_next_delta()[source]

Decode one delta data from delta_bits attribute. Later delete decoded data from delta_bits.

Return type:tuple (bool, int)
Returns:(was this delta special, value of delta)
get_digi()[source]

Get Digi channel status. This channel contains data such as battery level, on off button status, trigger status.

For VLDelta Data packet, which can contain multiple information in digi channel, this is done by taking binary alternative of all digi channel values.

Return type:number
Returns:byte containing flags (on/off button etc.) set in packet
set_vldelta_info(vldelta_info)[source]

Set VLDelta Info (user should obtain one from device before calling decode method).

Parameters:vldelta_info (VLDeltaInfo) – packet of type vldelta info containing divider list
class obci.drivers.eeg.tmsi.VLDeltaInfo[source]

Bases: obci.drivers.eeg.tmsi.Packet

Packet containing VL Delta information (like transmission frequency divider).

get_divider_list(number_of_channels)[source]

Decode dividers list from tha packet.

Parameters:number_of_channels (number) – number of data channels (not including digi and saw channels)
Return type:list of ints
Returns:list of all dividers (including digi and saw channels)
get_trans_freq_div()[source]

Returns value of transmission frequency divider from current packet.

Return type:number
Returns:transmission frequency divider
obci.drivers.eeg.tmsi.WORD_SIZE = 2

word size in bytes

obci.drivers.eeg.tmsi.bits_to_num(bits)[source]

Convert bit representation of a number (as large as you can imagine) back into number - int.

Parameters:bits (list of ints) – binary representation of a number
Return type:number
Returns:number represented by a given list of bits
obci.drivers.eeg.tmsi.calculate_checksum(data)[source]

Calculates checksum of a packet and return two byte (one word) string containing it.

Parameters:data (string) – data we want checksum of
Return type:string (two byte) representing checksum
Returns:checksum of data
obci.drivers.eeg.tmsi.decode_tmsi_bluetooth_number(data)[source]

Convert number in TMSi internal format into int.

Parameters:data (string (3 bytes)) – number represented in internal TMSi format
Return type:int
Returns:number after conversion
obci.drivers.eeg.tmsi.encode_tmsi_bluetooth_number(num)[source]

Convert number into TMSi internal format.

Parameters:num (int) – number to be converted
Return type:string (3 bytes)
Returns:number represented in internal TMSi format
obci.drivers.eeg.tmsi.num_to_bits(num)[source]

Convert number into its binary representation (list of bits). Number has to be from 0..255 range.

Parameters:num (number) – number to be converted into bit representation
Return type:list of ints
Returns:list of bits representing number num
obci.drivers.eeg.tmsi.number_to_string_word(number)[source]

Convert a number 0..65535 to two byte string representation. First byte is less significant.

Parameters:number (number) – number to be converted.
Return type:string
Returns:two byte string containing representation of a word.
obci.drivers.eeg.tmsi.string_word_to_number(data)[source]

Convert a two byte string representation of a number back into number. First byte is less significant.

Parameters:data (string) – two byte string containing representation of a word.
Return type:number
Returns:a number described by data parameter.

Module contents