obci.drivers.eeg package¶
Subpackages¶
Submodules¶
obci.drivers.eeg.amplifier_file module¶
-
class
obci.drivers.eeg.amplifier_file.
AmplifierFile
(addresses)[source]¶ Bases:
obci.drivers.eeg.binary_driver_wrapper.BinaryDriverWrapper
-
got_trigger
(ts)[source]¶ Got trigger from the drivers. Let`s send next tag (or other message) with ts as its realtime timestamp
-
obci.drivers.eeg.amplifier_virtual module¶
-
class
obci.drivers.eeg.amplifier_virtual.
AmplifierVirtual
(addresses)[source]¶ Bases:
obci.drivers.eeg.binary_driver_wrapper.BinaryDriverWrapper
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
-
desc_params
= {'physical_channels_no': 'physical_channels', 'sampling_rates': 'sampling_rates', 'amplifier_name': 'name', 'channels_info': 'channels'}¶
-
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.
obci.drivers.eeg.tags_to_mxmsg module¶
Bases:
object
Bases:
object
Bases:
object
Bases:
object
For every tag in tags find its corresponding handler
>>> 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'}¶
-
-
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¶
-
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.
-
-
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
-
-
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: 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: 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
-
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: 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: Returns: new Packet instance.
-
-
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
-
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
-
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).
-
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.