Technical Reference:State Definition

From BCI2000 Wiki
Jump to navigation Jump to search

This page describes the concept of BCI2000 states, in conjunction with their textual representation as a "state line".

For information about how to access state values from code, please refer to Programming Reference:Environment Class. For information about individual states, please refer to User Reference:States.

State Concept

States are variables that represent the internal state of a BCI2000 system as it is evolving over time in response to:

  • brain signal input
  • user interaction through the operator interface
  • trial sequencing by the application module.

Typical quantities/qualities encoded by states are:

  • whether the system is running or suspended
  • the time when a block of data was recorded
  • stimulus or task being presented
  • the classification result
  • the state of an external marker (trigger) to be saved for off-line analysis.

Typically, state values change once per block of data, or once per trial, but are recorded per-sample in case better resolution is required. In a BCI2000 data file, the full set of states is stored along with the data, allowing for reconstruction of on-line system state off-line.

Kinds of States

Depending on subtle differences in behavior, states come in three different flavors, or kinds. All of them are recorded per-sample, and all of them are available as "States" when reading a data file.

Events

These are only available in source modules. Events are states that can be written to asynchronously, using the [[1]] interface. Event data are collected in a queue along with time stamps, and aligned to samples with a maximum resolution of 1ms immediately after a new block of data has been recorded.

Streams

Similar to events, streams are only available in source modules. Streams are states that are intended to be used like additional source channels, being recorded synchronously with incoming brain signals. For an example how to use streams in conjunction with the BufferedADC class in a BCI2000 source module, see [tutorial].

When the value of a stream is set for a particular sample position in the current data block, it does not affect further samples.

States

The third kind of states is just called State and behaves specially in that setting a state at a particular sample position in the current data block will set it to that value for all future time points. To ensure proper behavior of states at block boundaries, a special carryover value exists at the end of the state vector that does not correspond to any sample position but is used to initialize a state's values when a new block of brain signal data arrives.

State Vector

In a BCI2000 system, a collection of states is maintained as a State List. For each state present in that state list, its value is kept as a range of bits in a bit vector called State Vector. BCI2000 modules and filters may read and write state values during processing. The state vector's content is saved, in its binary form, into BCI2000 data files per-block. Using the ByteLocation, BitLocation, and Length fields from the state definitions present in a file, a state's value may be read from the data file.

A state vector is a narrowly packed bit field in little endian ordering. This implies that, for a state containing more than a single bit, more significant bits are placed at higher bit and byte locations.

As an example, consider a state vector consisting of a 1-bit state "Running", and a 16-bit state "SourceTime". This will result in a three-byte state vector layout like this:

State Vector Byte 0 State Vector Byte 1 State Vector Byte 2
0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7
Running SourceTime unused
0 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15  

To make reading and writing of state values more efficient, padding states may be present in a state vector. They don't carry information but avoid states to extend across byte boundaries, and provide additional bytes required to access full 4-byte values. To separate padding states from actual states, padding states' names are formed from two underscores, the word "pad", and a current number as in __pad0, __pad1, __pad2, and so on.

State Lines

State lines are a human-readable format used to represent individual states in

Core modules and the operator module use this format to communicate in the system initialization phase, as well as during system performance and for system termination.

The format of a state line is

Name Length Value ByteLocation BitLocation CRLF

where Length refers to the number of bits used to represent the state's value, and ByteLocation and BitLocation refer to its position in the State Vector, with BitLocation ranging from 0 to 7.

Depending on the context of a state line, one or more of its fields will be redundant:

  • In a State message sent from a core module to the operator module, ByteLocation will be ignored, and BitLocation will change its meaning, and transport information about the state kind (see below).
  • In a State line contained in a data file, the Value field matches the state's value stored with the first block of data samples.
  • If BitLocation is negative, it represents the state variable's kind. The following values are defined:
-1 Padding state, -2 State kind, -3 Event kind, -4 Stream kind.

Generally, the Value field specifies an initial value of a state. Actual values are stored in the State Vector data structure.

State values are interpreted as unsigned integers, and limited to 32 bit in the current implementation (as defined by the State::ValueType typedef in BCI2000/src/shared/types/State.h).

See also

User Reference:States, Technical Reference:Parameter Definition, Programming Reference:Events, Programming Reference:States