<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://www.bci2000.org/mediawiki/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Atennissen</id>
	<title>BCI2000 Wiki - User contributions [en]</title>
	<link rel="self" type="application/atom+xml" href="https://www.bci2000.org/mediawiki/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Atennissen"/>
	<link rel="alternate" type="text/html" href="https://www.bci2000.org/mediawiki/index.php/Special:Contributions/Atennissen"/>
	<updated>2026-07-02T13:18:16Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.43.6</generator>
	<entry>
		<id>https://www.bci2000.org/mediawiki/index.php?title=P300_Off-line_Analysis_Tutorial&amp;diff=1795</id>
		<title>P300 Off-line Analysis Tutorial</title>
		<link rel="alternate" type="text/html" href="https://www.bci2000.org/mediawiki/index.php?title=P300_Off-line_Analysis_Tutorial&amp;diff=1795"/>
		<updated>2007-05-22T20:11:21Z</updated>

		<summary type="html">&lt;p&gt;Atennissen: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Starting an Analysis Session==&lt;br /&gt;
Every recording session has its own history. It is very difficult to say in advance what might happen during the recording. So we will assume that everything was perfect (the subject collaborated, no channel went lost, etc); later on we will consider the main causes of contamination, how to recognize it and what to do. &lt;br /&gt;
&lt;br /&gt;
If the recording session runs smoothly, you should now have eight files named TestSubjS001R01.dat to TestSubjS001R08.dat, in the folder c:\bci2000\data\Mu\TestSubj, corresponding to the eight runs, respectively. &lt;br /&gt;
&lt;br /&gt;
Before you start the analysis you should locate, on your hard disk, the correct montage file. This is a file that describes the list of channels that were acquired. In this tutorial we will use OneAndOnly_16ch.eloc.txt, which is located in the folder C:\BCI2000\Tutorial\Montages\. If you need to edit the *.mmf file, check its data format. &lt;br /&gt;
&lt;br /&gt;
==Opening Files with Mario==&lt;br /&gt;
After having run mario.exe, press &amp;quot;Select Data Files&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
[[Image:P300_1.jpg]]&lt;br /&gt;
&lt;br /&gt;
A dialog window will ask you to select the dat files. You can either select a single data file, or select multiple files. This time, we will select all files in the dataset. &lt;br /&gt;
&lt;br /&gt;
A green box will surround the Raw Data box in the main window. &lt;br /&gt;
&lt;br /&gt;
As an optional (but recommended) operation, click on the LOAD MONTAGE button and choose the mmf file. This will allow you to see the labels of each channel and allow you to apply spatial filters that depend on the electrode position. &lt;br /&gt;
&lt;br /&gt;
You can load an additional parameter file with choices different from those used in the experiment. &lt;br /&gt;
&lt;br /&gt;
At this point, you can check that P300 is selected in the Analysis menu (indicating that a P300 dataset has been recognized) and select the LOAD DATA button to confirm your choices. This will enable the EDIT CHANNEL LIST button that you can use to select the channels you want to include in your analysis.&lt;br /&gt;
&lt;br /&gt;
==Selecting Channels==&lt;br /&gt;
&lt;br /&gt;
When you select the EDIT CHANNEL LIST button, two forms will show you the channel list (valid ones and not-valid ones) and an image showing valid channels and their location. &lt;br /&gt;
&lt;br /&gt;
Clicking on Add and Remove buttons allows you to move a channel from one list to the other enabling or disabling it. &lt;br /&gt;
&lt;br /&gt;
==Selecting the Spatial Filter ==&lt;br /&gt;
&lt;br /&gt;
Return to the main window to choose which filter to apply for your analysis, selecting from the following filter choices: &lt;br /&gt;
&lt;br /&gt;
*RAW&lt;br /&gt;
*CAR&lt;br /&gt;
*Large Laplacian &lt;br /&gt;
*Small Laplacian &lt;br /&gt;
&lt;br /&gt;
Common Average Reference (CAR) will be fine for most of the situations. &lt;br /&gt;
&lt;br /&gt;
We hope soon, to release a user defined solution for any custom analysis. &lt;br /&gt;
&lt;br /&gt;
==Feature Extraction Analysis==&lt;br /&gt;
The Analysis field in the Feature Extraction panel will appear automatically depending on the files loaded. The Feature Extractor field shows the only currently available option (MEM).&lt;br /&gt;
You can view/edit analysis details by clicking &amp;quot;Set Analysis Details&amp;quot;&lt;br /&gt;
&lt;br /&gt;
[[Image:P300_2.jpg]]&lt;br /&gt;
&lt;br /&gt;
This form reports all the remaining settings for the P300 analysis. Most of the values are set as default values. With settings such as the ones reported in this figure, the analysis software will: &lt;br /&gt;
&lt;br /&gt;
*sample the spectrum at points starting from 0.1 Hz to 15 Hz&lt;br /&gt;
*take a 650 ms long epoch of data.&lt;br /&gt;
&lt;br /&gt;
You can modify these settings according to your aims. When you are finished, remember to confirm your choices by clicking on DONE. It will allow the program accept changes. &lt;br /&gt;
&lt;br /&gt;
At this point you can start the analysis by pressing the Evaluate and Plot button.&lt;br /&gt;
&lt;br /&gt;
[[Image:P300_3.jpg]]&lt;br /&gt;
&lt;br /&gt;
==View results==&lt;br /&gt;
The first figure that appears is the R-square matrix (channels x elapsed time after stimulus)&lt;br /&gt;
&lt;br /&gt;
===R-square Matrix===&lt;br /&gt;
The r-square matrix highlights the most relevant ERP features for the separation of potentials due to frequent or rare stimuli.&lt;br /&gt;
&lt;br /&gt;
[[Image:P300_4.jpg]]&lt;br /&gt;
&lt;br /&gt;
Each row of the matrix is related to a single channel, while a column represents a fixed latency. The color codes the statistical significance of the difference between the two kinds of evoked potentials. &lt;br /&gt;
&lt;br /&gt;
Thus a red color would mean that the ERP consequent to a rare stimulus is significantly more positive than the ERP consequent to a frequent stimulus.&lt;br /&gt;
&lt;br /&gt;
This figure is independent of the channel and latency settings that were set in the parameter dialog (since it summarizes all results). &lt;br /&gt;
&lt;br /&gt;
Clicking on the matrix will modify the channel/latency settings for the other figures; in fact the cell of the matrix that was clicked is characterized by one channel and one latency, whose waveform and topography (respectively) will be shown in the other two figures.&lt;br /&gt;
&lt;br /&gt;
You can choose whether to overwrite or to put the most recently evoked figures beside the previous one. Two sets of waveform/topography figures are available, and are linked to the click of the left or right mouse button.&lt;br /&gt;
&lt;br /&gt;
Clicking on any point of map will open four more windows: &lt;br /&gt;
&lt;br /&gt;
*Amplitude waveforms at selected channel(s) &lt;br /&gt;
*Topographic plots at selected latency(ies) &lt;br /&gt;
*ERP response to each stimulus &lt;br /&gt;
*An off-line prediction of the string read&lt;br /&gt;
&lt;br /&gt;
===Amplitude Waveform===&lt;br /&gt;
The whole timecourse of ERPs generated are displayed in the top panel, regardless of the specific stimulus (line of letters) that generated it. Rare ERPs are plotted in solid lines, while frequent ERPs are dotted. If two channels were selected in the P300 parameter dialog, they are plotted in red and in blue, respectively.&lt;br /&gt;
&lt;br /&gt;
[[Image:P300_5.jpg]]&lt;br /&gt;
&lt;br /&gt;
The bottom panel shows the r-square time course. It is roughly proportional to the difference between rare and frequent ERPs, but since r-square is sensitive to the dispersion (variance) of single trials, small differences in amplitude can result in a high r-square, if they are very reproducible.&lt;br /&gt;
&lt;br /&gt;
Topographic plots. This figure represents the scalp distribution of the r-square.&lt;br /&gt;
&lt;br /&gt;
[[Image:P300_6.jpg]]&lt;br /&gt;
&lt;br /&gt;
The color coding is the same as the r-square matrix figure, and values on each channel are interpolated to create a continuous bidimensional map. The higher the number of electrodes, the more accurate is the map. With Surface Laplacian spatial filteriing, the number of channels shown on the scalp may not coincide with the whole number of electrodes, since the value of the laplacian is not computed on the border channels.&lt;br /&gt;
&lt;br /&gt;
===ERP Response===&lt;br /&gt;
&lt;br /&gt;
[[Image:P300_7.jpg]]&lt;br /&gt;
&lt;br /&gt;
The figure shows the medium temporal course for the 12 stimuli. Red graphs are rare events while blue ones are frequent events.&lt;br /&gt;
&lt;br /&gt;
===String Prediction===&lt;br /&gt;
Mario also allows you to check the word that the BCI2000 system would have predicted if the current feature was used online.&lt;br /&gt;
&lt;br /&gt;
[[Image:P300_8.jpg]]&lt;br /&gt;
&lt;br /&gt;
In this example, since the sequence should have been SPELLWITHBCI, only 4 characters out of 12 (33%) have been correctly predicted. This score is well above chance, though quite inefficient.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{| border=&amp;quot;3&amp;quot; cellspacing=&amp;quot;5&amp;quot; cellpadding=&amp;quot;20&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
|S&lt;br /&gt;
|P&lt;br /&gt;
|E&lt;br /&gt;
|L&lt;br /&gt;
|L&lt;br /&gt;
|W&lt;br /&gt;
|I&lt;br /&gt;
|T&lt;br /&gt;
|H&lt;br /&gt;
|B&lt;br /&gt;
|C&lt;br /&gt;
|I&lt;br /&gt;
|- &lt;br /&gt;
|style=&amp;quot;background:#ff3322&amp;quot; |4&lt;br /&gt;
|style=&amp;quot;background:#ff3322&amp;quot; |M&lt;br /&gt;
|E&lt;br /&gt;
|L&lt;br /&gt;
|L&lt;br /&gt;
|style=&amp;quot;background:#ff3322&amp;quot; |4&lt;br /&gt;
|style=&amp;quot;background:#ff3322&amp;quot; |_&lt;br /&gt;
|T&lt;br /&gt;
|style=&amp;quot;background:#ff3322&amp;quot; |A&lt;br /&gt;
|style=&amp;quot;background:#ff3322&amp;quot; |K&lt;br /&gt;
|style=&amp;quot;background:#ff3322&amp;quot; |G&lt;br /&gt;
|style=&amp;quot;background:#ff3322&amp;quot; |4&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In summary, we must select the latency and the channel where the maxima of an ERP component, whose spatio-temporal shape is compatible with the P300 phenomenon, occurs. Testing the speller can suggest which component has the highest probability to predict the user&#039;s selected letter.&lt;/div&gt;</summary>
		<author><name>Atennissen</name></author>
	</entry>
	<entry>
		<id>https://www.bci2000.org/mediawiki/index.php?title=Programming_Tutorial:Implementing_a_Signal_Processing_Filter&amp;diff=1794</id>
		<title>Programming Tutorial:Implementing a Signal Processing Filter</title>
		<link rel="alternate" type="text/html" href="https://www.bci2000.org/mediawiki/index.php?title=Programming_Tutorial:Implementing_a_Signal_Processing_Filter&amp;diff=1794"/>
		<updated>2007-05-22T15:55:36Z</updated>

		<summary type="html">&lt;p&gt;Atennissen: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This tutorial shows you how to derive a new filter class from&lt;br /&gt;
&amp;lt;tt&amp;gt;GenericFilter&amp;lt;/tt&amp;gt;, how to check preconditions, initialize your&lt;br /&gt;
filter,&lt;br /&gt;
and process data.&lt;br /&gt;
It will also show you how to visualize the output signal of the filter and present it&lt;br /&gt;
to the operator user.&lt;br /&gt;
&lt;br /&gt;
==A simple low pass filter==&lt;br /&gt;
We want to implement a low pass filter with a time constant &amp;lt;math&amp;gt;T&amp;lt;/math&amp;gt; (given&lt;br /&gt;
in units&lt;br /&gt;
of a sample&#039;s duration), a sequence &amp;lt;math&amp;gt;S_{in,t}&amp;lt;/math&amp;gt; as input and a sequence&lt;br /&gt;
&amp;lt;math&amp;gt;S_{out,t}&amp;lt;/math&amp;gt; as output (where &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; is an sample index proportional to&lt;br /&gt;
time), and obeying&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;S_{out, 0} = \left( 1-e^{-1/T} \right) S_{in, 0}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;S_{out, t} = e^{-1/T} S_{out, t-1} + \left( 1-e^{-1/T} \right) S_{in, t}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==The filter skeleton==&lt;br /&gt;
&lt;br /&gt;
The resulting filter class is to be called &amp;lt;tt&amp;gt;LPFilter&amp;lt;/tt&amp;gt;.&lt;br /&gt;
We create two new files, &amp;lt;tt&amp;gt;LPFilter.h&amp;lt;/tt&amp;gt;, and&lt;br /&gt;
&amp;lt;tt&amp;gt;LPFilter.cpp&amp;lt;/tt&amp;gt;,&lt;br /&gt;
and put a minimal filter declaration into &amp;lt;tt&amp;gt;LPFilter.h&amp;lt;/tt&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#ifndef LP_FILTER_H&lt;br /&gt;
#define LP_FILTER_H&lt;br /&gt;
&lt;br /&gt;
#include &amp;quot;GenericFilter.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
class LPFilter : public GenericFilter&lt;br /&gt;
{&lt;br /&gt;
 public:&lt;br /&gt;
   LPFilter();&lt;br /&gt;
   ~LPFilter();&lt;br /&gt;
&lt;br /&gt;
   void Preflight( const SignalProperties&amp;amp;, SignalProperties&amp;amp; ) const;&lt;br /&gt;
   void Initialize();&lt;br /&gt;
   void Process( const GenericSignal*, GenericSignal* );&lt;br /&gt;
};&lt;br /&gt;
#endif // LP_FILTER_H&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Into &amp;lt;tt&amp;gt;LPFilter.cpp&amp;lt;/tt&amp;gt; we put the lines&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;quot;PCHIncludes.h&amp;quot; // Make the compiler&#039;s Pre-Compiled Headers feature happy&lt;br /&gt;
#pragma hdrstop&lt;br /&gt;
&lt;br /&gt;
#include &amp;quot;LPFilter.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
#include &amp;quot;MeasurementUnits.h&amp;quot;&lt;br /&gt;
#include &amp;quot;BCIError.h&amp;quot;&lt;br /&gt;
#include &amp;lt;vector&amp;gt;&lt;br /&gt;
#include &amp;lt;cmath&amp;gt;&lt;br /&gt;
&lt;br /&gt;
using namespace std;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==The &amp;lt;tt&amp;gt;Process&amp;lt;/tt&amp;gt; function==&lt;br /&gt;
When implementing a filter, a good strategy is to begin with the&lt;br /&gt;
&amp;lt;tt&amp;gt;Process&amp;lt;/tt&amp;gt;&lt;br /&gt;
function, and to consider the remaining class member functions mere&lt;br /&gt;
helpers, mainly&lt;br /&gt;
determined by the code of &amp;lt;tt&amp;gt;Process&amp;lt;/tt&amp;gt;.&lt;br /&gt;
So we convert the filter prescription into the &amp;lt;tt&amp;gt;Process&amp;lt;/tt&amp;gt;&lt;br /&gt;
code, introducing member variables &#039;&#039;ad hoc&#039;&#039; , ignoring possible&lt;br /&gt;
error&lt;br /&gt;
conditions, and postponing efficiency considerations:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void LPFilter::Process( const GenericSignal* input, GenericSignal* output )&lt;br /&gt;
{&lt;br /&gt;
  // This implements the prescription&#039;s second line for all channels:&lt;br /&gt;
  for( size_t channel = 0; channel &amp;lt; input-&amp;gt;Channels(); ++channel )&lt;br /&gt;
  {&lt;br /&gt;
    for( size_t sample = 0; sample &amp;lt; input-&amp;gt;Elements(); ++sample )&lt;br /&gt;
    {&lt;br /&gt;
      mPreviousOutput[ channel ] *= mDecayFactor;&lt;br /&gt;
      mPreviousOutput[ channel ] +=&lt;br /&gt;
           ( *input )( channel, sample ) * ( 1.0 - mDecayFactor );&lt;br /&gt;
      ( *output )( channel, sample ) = mPreviousOutput[ channel ];&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==The &amp;lt;tt&amp;gt;Initialize&amp;lt;/tt&amp;gt; member function==&lt;br /&gt;
As you will notice when comparing &amp;lt;tt&amp;gt;Process&amp;lt;/tt&amp;gt; to the equations above, we introduced member variables representing these sub-expressions:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\texttt{mPreviousOutput[ ]}= S_{out, t-1}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\texttt{mDecayFactor} = e^{-1/T}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
We introduce these members into the class declaration, adding the&lt;br /&gt;
following lines&lt;br /&gt;
after the &amp;lt;tt&amp;gt;Process&amp;lt;/tt&amp;gt; declaration:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  private:&lt;br /&gt;
    float              mDecayFactor;&lt;br /&gt;
    std::vector&amp;lt;float&amp;gt; mPreviousOutput;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
The next step is to initialize these member variables, introducing&lt;br /&gt;
filter&lt;br /&gt;
parameters as needed. This is done in the &amp;lt;tt&amp;gt;Initialize&amp;lt;/tt&amp;gt; member&lt;br /&gt;
function --&lt;br /&gt;
we write it down without considering possible error conditions:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void LPFilter::Initialize( const SignalProperties&amp;amp; inputProperties,&lt;br /&gt;
                           const SignalProperties&amp;amp; outputProperties )&lt;br /&gt;
{&lt;br /&gt;
  // This will initialize all elements with 0,&lt;br /&gt;
  // implementing the first line of the filter prescription:&lt;br /&gt;
  mPreviousOutput.resize( inputProperties.Channels(), 0 );&lt;br /&gt;
&lt;br /&gt;
  float timeConstant = Parameter( &amp;quot;LPTimeConstant&amp;quot; );&lt;br /&gt;
  mDecayFactor = ::exp( -1.0 / timeConstant );&lt;br /&gt;
  mPreviousOutput.clear();&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Now this version is quite inconvenient for a user going to configure our filter&lt;br /&gt;
-- the time constant is given in units of a sample&#039;s duration, resulting in a&lt;br /&gt;
need to re-configure each time the sampling rate is changed.&lt;br /&gt;
A better idea is to let the user choose whether to give the&lt;br /&gt;
time constant in seconds or in sample blocks. &lt;br /&gt;
To achieve this, there is a utility class &amp;lt;tt&amp;gt;MeasurementUnits&amp;lt;/tt&amp;gt;&lt;br /&gt;
that has&lt;br /&gt;
a member &amp;lt;tt&amp;gt;ReadAsTime()&amp;lt;/tt&amp;gt;, returning values in units of sample&lt;br /&gt;
blocks which&lt;br /&gt;
is the natural time unit in a BCI2000 system.&lt;br /&gt;
Writing a number followed by an &amp;quot;s&amp;quot; will allow the user to specify a&lt;br /&gt;
time value in&lt;br /&gt;
seconds; writing a number without the &amp;quot;s&amp;quot; will be interpreted as sample blocks.&lt;br /&gt;
Thus, our user friendly version of &amp;lt;tt&amp;gt;Initialize&amp;lt;/tt&amp;gt; reads&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void LPFilter::Initialize()&lt;br /&gt;
{&lt;br /&gt;
  // Get the time constant in units of a sample block&#039;s duration:&lt;br /&gt;
  float timeConstant = MeasurementUnits::ReadAsTime( Parameter(&lt;br /&gt;
  &amp;quot;LPTimeConstant&amp;quot; ) );&lt;br /&gt;
  // Convert it into units of a sample&#039;s duration:&lt;br /&gt;
  timeConstant *= Parameter( &amp;quot;SampleBlockSize&amp;quot; );&lt;br /&gt;
&lt;br /&gt;
  mDecayFactor = ::exp( -1.0 / timeConstant );&lt;br /&gt;
  mPreviousOutput.clear();&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
==The &amp;lt;tt&amp;gt;Preflight&amp;lt;/tt&amp;gt; function==&lt;br /&gt;
Up to now, we have not considered any error conditions that might occur&lt;br /&gt;
during&lt;br /&gt;
execution of our filter code. Scanning through the &amp;lt;tt&amp;gt;Process&amp;lt;/tt&amp;gt;&lt;br /&gt;
and&lt;br /&gt;
&amp;lt;tt&amp;gt;Initialize&amp;lt;/tt&amp;gt; code, we identify a number of implicit&lt;br /&gt;
assumptions:&lt;br /&gt;
  &lt;br /&gt;
#The time constant is not zero -- otherwise, a division by zero will occur. &lt;br /&gt;
#The time constant is not negative -- otherwise, the output signal is no longer guaranteed to be finite, and a numeric overflow may occur. &lt;br /&gt;
#Input and output signal pointers are assumed to point to valid locations in memory. &lt;br /&gt;
#The output signal is assumed to hold at least as much data as the input signal contains. &lt;br /&gt;
The first two assumptions may be violated if a user enters an illegal&lt;br /&gt;
value into the LPTimeConstant parameter; we need to make sure that an&lt;br /&gt;
error&lt;br /&gt;
is reported, and no code is executed that depends on these two&lt;br /&gt;
assumptions.&lt;br /&gt;
The third assumption will hold if the framework code does what it is&lt;br /&gt;
supposed&lt;br /&gt;
to do, so we do not need to check for it.&lt;br /&gt;
For the last assumption, we request an appropriate output signal from&lt;br /&gt;
the&lt;br /&gt;
&amp;lt;tt&amp;gt;Preflight&amp;lt;/tt&amp;gt; function. Thus, the &amp;lt;tt&amp;gt;Preflight&amp;lt;/tt&amp;gt; code reads&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void LPFilter::Preflight( const SignalProperties&amp;amp; inputProperties,&lt;br /&gt;
                                SignalProperties&amp;amp; outputProperties ) const&lt;br /&gt;
{&lt;br /&gt;
  float LPTimeConstant &lt;br /&gt;
    = MeasurementUnits::ReadAsTime( Parameter( &amp;quot;LPTimeConstant&amp;quot; ) );&lt;br /&gt;
  LPTimeConstant *= Parameter( &amp;quot;SampleBlockSize&amp;quot; );&lt;br /&gt;
  // The PreflightCondition macro will automatically generate an error&lt;br /&gt;
  // message if its argument evaluates to false.&lt;br /&gt;
  // However, we need to make sure that its argument is user-readable&lt;br /&gt;
  // -- this is why we chose a variable name that matches the&lt;br /&gt;
  parameter&lt;br /&gt;
  // name.&lt;br /&gt;
  PreflightCondition( LPTimeConstant &amp;gt; 0 );&lt;br /&gt;
  // Alternatively, we might write:&lt;br /&gt;
  if( LPTimeConstant &amp;lt;= 0 )&lt;br /&gt;
    bcierr &amp;lt;&amp;lt; &amp;quot;The LPTimeConstant parameter must be greater 0&amp;quot; &amp;lt;&amp;lt; endl;&lt;br /&gt;
&lt;br /&gt;
  // Request output signal properties:&lt;br /&gt;
  outputProperties = inputProperties;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Constructor and destructor==&lt;br /&gt;
Because we do not explicitly acquire resources, nor perform&lt;br /&gt;
asynchronous&lt;br /&gt;
operations, there is nothing to be done inside the &amp;lt;tt&amp;gt;LPFilter&amp;lt;/tt&amp;gt;&lt;br /&gt;
&#039;&#039;destructor&#039;&#039; .&lt;br /&gt;
Our &#039;&#039;constructor&#039;&#039;  will contain initializers for the members we&lt;br /&gt;
declared,&lt;br /&gt;
and a BCI2000 parameter definition for LPTimeConstant:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
LPFilter::LPFilter()&lt;br /&gt;
: mDecayFactor( 0 ),&lt;br /&gt;
  mPreviousOutput( 0 )&lt;br /&gt;
{&lt;br /&gt;
  BEGIN_PARAMETER_DEFINITIONS&lt;br /&gt;
    &amp;quot;Filtering float LPTimeConstant= 16s&amp;quot;&lt;br /&gt;
      &amp;quot; 16s 0 0 // time constant for the low pass filter in blocks or&lt;br /&gt;
      seconds&amp;quot;,&lt;br /&gt;
  END_PARAMETER_DEFINITIONS&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
LPFilter::~LPFilter()&lt;br /&gt;
{&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Filter instantiation==&lt;br /&gt;
To have our filter instantiated in a signal processing module, we add&lt;br /&gt;
a line&lt;br /&gt;
containing a &amp;lt;tt&amp;gt;Filter&amp;lt;/tt&amp;gt; statement to the module&#039;s&lt;br /&gt;
&amp;lt;tt&amp;gt;PipeDefinition.cpp&amp;lt;/tt&amp;gt;.&lt;br /&gt;
This statement expects a string parameter which is used to determine&lt;br /&gt;
the filter&#039;s&lt;br /&gt;
position in the filter chain.&lt;br /&gt;
If we want to use the filter in the AR Signal Processing module, and&lt;br /&gt;
place it after&lt;br /&gt;
the &amp;lt;tt&amp;gt;SpatialFilter&amp;lt;/tt&amp;gt;, we add&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;quot;LPFilter.h&amp;quot;&lt;br /&gt;
...&lt;br /&gt;
Filter( LPFilter, 2.B1 );&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
to the file &amp;lt;tt&amp;gt;SignalProcessing/AR/PipeDefinition.cpp&amp;lt;/tt&amp;gt;.&lt;br /&gt;
Now, if we compile and link the AR Signal Processing module, we get an&lt;br /&gt;
&amp;quot;unresolved&lt;br /&gt;
external&amp;quot; linker error that reminds us to add our&lt;br /&gt;
&amp;lt;tt&amp;gt;LPFilter.cpp&amp;lt;/tt&amp;gt; to that module&#039;s project.&lt;br /&gt;
&lt;br /&gt;
==Visualizing filter output==&lt;br /&gt;
In order to present the LPFilter&#039;s output signal in an operator window, we introduce a member of type&lt;br /&gt;
&amp;lt;tt&amp;gt;GenericVisualization&amp;lt;/tt&amp;gt;&lt;br /&gt;
into our filter class, adding&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;quot;GenericVisualization.h&amp;quot;&lt;br /&gt;
...&lt;br /&gt;
class LPFilter : public GenericFilter&lt;br /&gt;
{&lt;br /&gt;
...&lt;br /&gt;
  private:&lt;br /&gt;
...&lt;br /&gt;
    GenericVisualization  mSignalVis;&lt;br /&gt;
};&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;GenericVisualization&amp;lt;/tt&amp;gt;&#039;s constructor takes a one-byte&lt;br /&gt;
visualization&lt;br /&gt;
ID as a parameter; we need to get a unique ID in order to get our data&lt;br /&gt;
routed&lt;br /&gt;
to the correct operator window.&lt;br /&gt;
This can be done by adding an entry&lt;br /&gt;
&amp;lt;tt&amp;gt;LowPass&amp;lt;/tt&amp;gt; at the end of the &amp;lt;tt&amp;gt;SOURCEID&amp;lt;/tt&amp;gt; enumeration in&lt;br /&gt;
the file&lt;br /&gt;
&amp;lt;tt&amp;gt;shared/defines.h&amp;lt;/tt&amp;gt;.&lt;br /&gt;
Then, in our &amp;lt;tt&amp;gt;.cpp&amp;lt;/tt&amp;gt; file, we add&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;quot;defines.h&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
and change the &amp;lt;tt&amp;gt;LPFilter&amp;lt;/tt&amp;gt; constructor to read&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
LPFilter::LPFilter()&lt;br /&gt;
: mDecayFactor( 0 ),&lt;br /&gt;
  mPreviousOutput( 0 ),&lt;br /&gt;
  mSignalVis( SOURCEID::LowPass )&lt;br /&gt;
{&lt;br /&gt;
  BEGIN_PARAMETER_DEFINITIONS&lt;br /&gt;
    &amp;quot;Filtering float LPTimeConstant= 16s&amp;quot;&lt;br /&gt;
      &amp;quot; 16s 0 0 // time constant for the low pass filter in blocks or&lt;br /&gt;
      seconds&amp;quot;,&lt;br /&gt;
    &amp;quot;Visualize int VisualizeLowPass= 1&amp;quot;&lt;br /&gt;
      &amp;quot; 1 0 1 // visualize low pass output signal (0=no, 1=yes)&amp;quot;,&lt;br /&gt;
    &amp;quot;Visualize int LPVisMin= -100 0 0 0 &amp;quot;&lt;br /&gt;
      &amp;quot;// low pass visualization min value&amp;quot;,&lt;br /&gt;
    &amp;quot;Visualize int LPVisMax= 100 0 0 0 &amp;quot;&lt;br /&gt;
      &amp;quot;// low pass visualization max value&amp;quot;,&lt;br /&gt;
  END_PARAMETER_DEFINITIONS&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
where LPVisMin and LPVisMax parameters determine the default scaling&lt;br /&gt;
of the&lt;br /&gt;
displayed signal; these parameters may even be reversed, resulting in&lt;br /&gt;
an inversion&lt;br /&gt;
of the displayed signal, so there is no need to check these parameters&lt;br /&gt;
from&lt;br /&gt;
&amp;lt;tt&amp;gt;Preflight&amp;lt;/tt&amp;gt;.&lt;br /&gt;
In &amp;lt;tt&amp;gt;Initialize&amp;lt;/tt&amp;gt;, we add&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  mSignalVis.Send( CFGID::WINDOWTITLE, &amp;quot;Low Pass&amp;quot; );&lt;br /&gt;
  mSignalVis.Send( CFGID::graphType, CFGID::polyline );&lt;br /&gt;
  mSignalVis.Send( CFGID::MINVALUE, Parameter( &amp;quot;LPVisMin&amp;quot; ) );&lt;br /&gt;
  mSignalVis.Send( CFGID::MAXVALUE, Parameter( &amp;quot;LPVisMax&amp;quot; ) );&lt;br /&gt;
  mSignalVis.Send( CFGID::NUMSAMPLES, 2 * Parameter( &amp;quot;SamplingRate&amp;quot; ) );&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Finally, to update the display in regular intervals, we add the&lt;br /&gt;
following at the&lt;br /&gt;
end of &amp;lt;tt&amp;gt;Process&amp;lt;/tt&amp;gt;:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  if( Parameter( &amp;quot;VisualizeLowPass&amp;quot; ) == 1 )&lt;br /&gt;
    mSignalVis.Send( output );&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
We might also send data to the already existing task log memo window,&lt;br /&gt;
adding&lt;br /&gt;
another member&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  GenericVisualization  mTaskLogVis;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
initializing it with&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
LPFilter::LPFilter()&lt;br /&gt;
: ...&lt;br /&gt;
  mTaskLogVis( SOURCEID::TASKLOG )&lt;br /&gt;
{&lt;br /&gt;
 ...&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
and, from inside &amp;lt;tt&amp;gt;Process&amp;lt;/tt&amp;gt;, writing some text to it as in&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  if( ( *output )( 0, 0 ) &amp;gt; 10 )&lt;br /&gt;
  {&lt;br /&gt;
    ostringstream oss;&lt;br /&gt;
    oss &amp;lt;&amp;lt; &amp;quot;LPFilter: (0,0) entry of output exceeds 10 and is &amp;quot;&lt;br /&gt;
        &amp;lt;&amp;lt; ( *output )( 0, 0 );&lt;br /&gt;
    mTaskLogVis.Send( oss.str() );&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>Atennissen</name></author>
	</entry>
	<entry>
		<id>https://www.bci2000.org/mediawiki/index.php?title=Programming_Tutorial:Implementing_a_Signal_Processing_Filter&amp;diff=1793</id>
		<title>Programming Tutorial:Implementing a Signal Processing Filter</title>
		<link rel="alternate" type="text/html" href="https://www.bci2000.org/mediawiki/index.php?title=Programming_Tutorial:Implementing_a_Signal_Processing_Filter&amp;diff=1793"/>
		<updated>2007-05-22T15:54:12Z</updated>

		<summary type="html">&lt;p&gt;Atennissen: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This tutorial shows you how to derive a new filter class from&lt;br /&gt;
&amp;lt;tt&amp;gt;GenericFilter&amp;lt;/tt&amp;gt;, how to check preconditions, initialize your&lt;br /&gt;
filter,&lt;br /&gt;
and process data.&lt;br /&gt;
It will also show you how to visualize a filter&#039;s output signal,&lt;br /&gt;
presenting it&lt;br /&gt;
to the operator user.&lt;br /&gt;
&lt;br /&gt;
==A simple low pass filter==&lt;br /&gt;
We want to implement a low pass filter with a time constant &amp;lt;math&amp;gt;T&amp;lt;/math&amp;gt; (given&lt;br /&gt;
in units&lt;br /&gt;
of a sample&#039;s duration), a sequence &amp;lt;math&amp;gt;S_{in,t}&amp;lt;/math&amp;gt; as input and a sequence&lt;br /&gt;
&amp;lt;math&amp;gt;S_{out,t}&amp;lt;/math&amp;gt; as output (where &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; is an sample index proportional to&lt;br /&gt;
time), and obeying&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;S_{out, 0} = \left( 1-e^{-1/T} \right) S_{in, 0}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;S_{out, t} = e^{-1/T} S_{out, t-1} + \left( 1-e^{-1/T} \right) S_{in, t}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==The filter skeleton==&lt;br /&gt;
&lt;br /&gt;
The resulting filter class is to be called &amp;lt;tt&amp;gt;LPFilter&amp;lt;/tt&amp;gt;.&lt;br /&gt;
We create two new files, &amp;lt;tt&amp;gt;LPFilter.h&amp;lt;/tt&amp;gt;, and&lt;br /&gt;
&amp;lt;tt&amp;gt;LPFilter.cpp&amp;lt;/tt&amp;gt;,&lt;br /&gt;
and put a minimal filter declaration into &amp;lt;tt&amp;gt;LPFilter.h&amp;lt;/tt&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#ifndef LP_FILTER_H&lt;br /&gt;
#define LP_FILTER_H&lt;br /&gt;
&lt;br /&gt;
#include &amp;quot;GenericFilter.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
class LPFilter : public GenericFilter&lt;br /&gt;
{&lt;br /&gt;
 public:&lt;br /&gt;
   LPFilter();&lt;br /&gt;
   ~LPFilter();&lt;br /&gt;
&lt;br /&gt;
   void Preflight( const SignalProperties&amp;amp;, SignalProperties&amp;amp; ) const;&lt;br /&gt;
   void Initialize();&lt;br /&gt;
   void Process( const GenericSignal*, GenericSignal* );&lt;br /&gt;
};&lt;br /&gt;
#endif // LP_FILTER_H&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Into &amp;lt;tt&amp;gt;LPFilter.cpp&amp;lt;/tt&amp;gt; we put the lines&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;quot;PCHIncludes.h&amp;quot; // Make the compiler&#039;s Pre-Compiled Headers feature happy&lt;br /&gt;
#pragma hdrstop&lt;br /&gt;
&lt;br /&gt;
#include &amp;quot;LPFilter.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
#include &amp;quot;MeasurementUnits.h&amp;quot;&lt;br /&gt;
#include &amp;quot;BCIError.h&amp;quot;&lt;br /&gt;
#include &amp;lt;vector&amp;gt;&lt;br /&gt;
#include &amp;lt;cmath&amp;gt;&lt;br /&gt;
&lt;br /&gt;
using namespace std;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==The &amp;lt;tt&amp;gt;Process&amp;lt;/tt&amp;gt; function==&lt;br /&gt;
When implementing a filter, a good strategy is to begin with the&lt;br /&gt;
&amp;lt;tt&amp;gt;Process&amp;lt;/tt&amp;gt;&lt;br /&gt;
function, and to consider the remaining class member functions mere&lt;br /&gt;
helpers, mainly&lt;br /&gt;
determined by the code of &amp;lt;tt&amp;gt;Process&amp;lt;/tt&amp;gt;.&lt;br /&gt;
So we convert the filter prescription into the &amp;lt;tt&amp;gt;Process&amp;lt;/tt&amp;gt;&lt;br /&gt;
code, introducing member variables &#039;&#039;ad hoc&#039;&#039; , ignoring possible&lt;br /&gt;
error&lt;br /&gt;
conditions, and postponing efficiency considerations:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void LPFilter::Process( const GenericSignal* input, GenericSignal* output )&lt;br /&gt;
{&lt;br /&gt;
  // This implements the prescription&#039;s second line for all channels:&lt;br /&gt;
  for( size_t channel = 0; channel &amp;lt; input-&amp;gt;Channels(); ++channel )&lt;br /&gt;
  {&lt;br /&gt;
    for( size_t sample = 0; sample &amp;lt; input-&amp;gt;Elements(); ++sample )&lt;br /&gt;
    {&lt;br /&gt;
      mPreviousOutput[ channel ] *= mDecayFactor;&lt;br /&gt;
      mPreviousOutput[ channel ] +=&lt;br /&gt;
           ( *input )( channel, sample ) * ( 1.0 - mDecayFactor );&lt;br /&gt;
      ( *output )( channel, sample ) = mPreviousOutput[ channel ];&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==The &amp;lt;tt&amp;gt;Initialize&amp;lt;/tt&amp;gt; member function==&lt;br /&gt;
As you will notice when comparing &amp;lt;tt&amp;gt;Process&amp;lt;/tt&amp;gt; to the equations above, we introduced member variables representing these sub-expressions:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\texttt{mPreviousOutput[ ]}= S_{out, t-1}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\texttt{mDecayFactor} = e^{-1/T}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
We introduce these members into the class declaration, adding the&lt;br /&gt;
following lines&lt;br /&gt;
after the &amp;lt;tt&amp;gt;Process&amp;lt;/tt&amp;gt; declaration:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  private:&lt;br /&gt;
    float              mDecayFactor;&lt;br /&gt;
    std::vector&amp;lt;float&amp;gt; mPreviousOutput;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
The next step is to initialize these member variables, introducing&lt;br /&gt;
filter&lt;br /&gt;
parameters as needed. This is done in the &amp;lt;tt&amp;gt;Initialize&amp;lt;/tt&amp;gt; member&lt;br /&gt;
function --&lt;br /&gt;
we write it down without considering possible error conditions:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void LPFilter::Initialize( const SignalProperties&amp;amp; inputProperties,&lt;br /&gt;
                           const SignalProperties&amp;amp; outputProperties )&lt;br /&gt;
{&lt;br /&gt;
  // This will initialize all elements with 0,&lt;br /&gt;
  // implementing the first line of the filter prescription:&lt;br /&gt;
  mPreviousOutput.resize( inputProperties.Channels(), 0 );&lt;br /&gt;
&lt;br /&gt;
  float timeConstant = Parameter( &amp;quot;LPTimeConstant&amp;quot; );&lt;br /&gt;
  mDecayFactor = ::exp( -1.0 / timeConstant );&lt;br /&gt;
  mPreviousOutput.clear();&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Now this version is quite inconvenient for a user going to configure our filter&lt;br /&gt;
-- the time constant is given in units of a sample&#039;s duration, resulting in a&lt;br /&gt;
need to re-configure each time the sampling rate is changed.&lt;br /&gt;
A better idea is to let the user choose whether to give the&lt;br /&gt;
time constant in seconds or in sample blocks. &lt;br /&gt;
To achieve this, there is a utility class &amp;lt;tt&amp;gt;MeasurementUnits&amp;lt;/tt&amp;gt;&lt;br /&gt;
that has&lt;br /&gt;
a member &amp;lt;tt&amp;gt;ReadAsTime()&amp;lt;/tt&amp;gt;, returning values in units of sample&lt;br /&gt;
blocks which&lt;br /&gt;
is the natural time unit in a BCI2000 system.&lt;br /&gt;
Writing a number followed by an &amp;quot;s&amp;quot; will allow the user to specify a&lt;br /&gt;
time value in&lt;br /&gt;
seconds; writing a number without the &amp;quot;s&amp;quot; will be interpreted as sample blocks.&lt;br /&gt;
Thus, our user friendly version of &amp;lt;tt&amp;gt;Initialize&amp;lt;/tt&amp;gt; reads&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void LPFilter::Initialize()&lt;br /&gt;
{&lt;br /&gt;
  // Get the time constant in units of a sample block&#039;s duration:&lt;br /&gt;
  float timeConstant = MeasurementUnits::ReadAsTime( Parameter(&lt;br /&gt;
  &amp;quot;LPTimeConstant&amp;quot; ) );&lt;br /&gt;
  // Convert it into units of a sample&#039;s duration:&lt;br /&gt;
  timeConstant *= Parameter( &amp;quot;SampleBlockSize&amp;quot; );&lt;br /&gt;
&lt;br /&gt;
  mDecayFactor = ::exp( -1.0 / timeConstant );&lt;br /&gt;
  mPreviousOutput.clear();&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
==The &amp;lt;tt&amp;gt;Preflight&amp;lt;/tt&amp;gt; function==&lt;br /&gt;
Up to now, we have not considered any error conditions that might occur&lt;br /&gt;
during&lt;br /&gt;
execution of our filter code. Scanning through the &amp;lt;tt&amp;gt;Process&amp;lt;/tt&amp;gt;&lt;br /&gt;
and&lt;br /&gt;
&amp;lt;tt&amp;gt;Initialize&amp;lt;/tt&amp;gt; code, we identify a number of implicit&lt;br /&gt;
assumptions:&lt;br /&gt;
  &lt;br /&gt;
#The time constant is not zero -- otherwise, a division by zero will occur. &lt;br /&gt;
#The time constant is not negative -- otherwise, the output signal is no longer guaranteed to be finite, and a numeric overflow may occur. &lt;br /&gt;
#Input and output signal pointers are assumed to point to valid locations in memory. &lt;br /&gt;
#The output signal is assumed to hold at least as much data as the input signal contains. &lt;br /&gt;
The first two assumptions may be violated if a user enters an illegal&lt;br /&gt;
value into the LPTimeConstant parameter; we need to make sure that an&lt;br /&gt;
error&lt;br /&gt;
is reported, and no code is executed that depends on these two&lt;br /&gt;
assumptions.&lt;br /&gt;
The third assumption will hold if the framework code does what it is&lt;br /&gt;
supposed&lt;br /&gt;
to do, so we do not need to check for it.&lt;br /&gt;
For the last assumption, we request an appropriate output signal from&lt;br /&gt;
the&lt;br /&gt;
&amp;lt;tt&amp;gt;Preflight&amp;lt;/tt&amp;gt; function. Thus, the &amp;lt;tt&amp;gt;Preflight&amp;lt;/tt&amp;gt; code reads&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void LPFilter::Preflight( const SignalProperties&amp;amp; inputProperties,&lt;br /&gt;
                                SignalProperties&amp;amp; outputProperties ) const&lt;br /&gt;
{&lt;br /&gt;
  float LPTimeConstant &lt;br /&gt;
    = MeasurementUnits::ReadAsTime( Parameter( &amp;quot;LPTimeConstant&amp;quot; ) );&lt;br /&gt;
  LPTimeConstant *= Parameter( &amp;quot;SampleBlockSize&amp;quot; );&lt;br /&gt;
  // The PreflightCondition macro will automatically generate an error&lt;br /&gt;
  // message if its argument evaluates to false.&lt;br /&gt;
  // However, we need to make sure that its argument is user-readable&lt;br /&gt;
  // -- this is why we chose a variable name that matches the&lt;br /&gt;
  parameter&lt;br /&gt;
  // name.&lt;br /&gt;
  PreflightCondition( LPTimeConstant &amp;gt; 0 );&lt;br /&gt;
  // Alternatively, we might write:&lt;br /&gt;
  if( LPTimeConstant &amp;lt;= 0 )&lt;br /&gt;
    bcierr &amp;lt;&amp;lt; &amp;quot;The LPTimeConstant parameter must be greater 0&amp;quot; &amp;lt;&amp;lt; endl;&lt;br /&gt;
&lt;br /&gt;
  // Request output signal properties:&lt;br /&gt;
  outputProperties = inputProperties;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Constructor and destructor==&lt;br /&gt;
Because we do not explicitly acquire resources, nor perform&lt;br /&gt;
asynchronous&lt;br /&gt;
operations, there is nothing to be done inside the &amp;lt;tt&amp;gt;LPFilter&amp;lt;/tt&amp;gt;&lt;br /&gt;
&#039;&#039;destructor&#039;&#039; .&lt;br /&gt;
Our &#039;&#039;constructor&#039;&#039;  will contain initializers for the members we&lt;br /&gt;
declared,&lt;br /&gt;
and a BCI2000 parameter definition for LPTimeConstant:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
LPFilter::LPFilter()&lt;br /&gt;
: mDecayFactor( 0 ),&lt;br /&gt;
  mPreviousOutput( 0 )&lt;br /&gt;
{&lt;br /&gt;
  BEGIN_PARAMETER_DEFINITIONS&lt;br /&gt;
    &amp;quot;Filtering float LPTimeConstant= 16s&amp;quot;&lt;br /&gt;
      &amp;quot; 16s 0 0 // time constant for the low pass filter in blocks or&lt;br /&gt;
      seconds&amp;quot;,&lt;br /&gt;
  END_PARAMETER_DEFINITIONS&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
LPFilter::~LPFilter()&lt;br /&gt;
{&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Filter instantiation==&lt;br /&gt;
To have our filter instantiated in a signal processing module, we add&lt;br /&gt;
a line&lt;br /&gt;
containing a &amp;lt;tt&amp;gt;Filter&amp;lt;/tt&amp;gt; statement to the module&#039;s&lt;br /&gt;
&amp;lt;tt&amp;gt;PipeDefinition.cpp&amp;lt;/tt&amp;gt;.&lt;br /&gt;
This statement expects a string parameter which is used to determine&lt;br /&gt;
the filter&#039;s&lt;br /&gt;
position in the filter chain.&lt;br /&gt;
If we want to use the filter in the AR Signal Processing module, and&lt;br /&gt;
place it after&lt;br /&gt;
the &amp;lt;tt&amp;gt;SpatialFilter&amp;lt;/tt&amp;gt;, we add&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;quot;LPFilter.h&amp;quot;&lt;br /&gt;
...&lt;br /&gt;
Filter( LPFilter, 2.B1 );&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
to the file &amp;lt;tt&amp;gt;SignalProcessing/AR/PipeDefinition.cpp&amp;lt;/tt&amp;gt;.&lt;br /&gt;
Now, if we compile and link the AR Signal Processing module, we get an&lt;br /&gt;
&amp;quot;unresolved&lt;br /&gt;
external&amp;quot; linker error that reminds us to add our&lt;br /&gt;
&amp;lt;tt&amp;gt;LPFilter.cpp&amp;lt;/tt&amp;gt; to that module&#039;s project.&lt;br /&gt;
&lt;br /&gt;
==Visualizing filter output==&lt;br /&gt;
In order to present the LPFilter&#039;s output signal in an operator window, we introduce a member of type&lt;br /&gt;
&amp;lt;tt&amp;gt;GenericVisualization&amp;lt;/tt&amp;gt;&lt;br /&gt;
into our filter class, adding&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;quot;GenericVisualization.h&amp;quot;&lt;br /&gt;
...&lt;br /&gt;
class LPFilter : public GenericFilter&lt;br /&gt;
{&lt;br /&gt;
...&lt;br /&gt;
  private:&lt;br /&gt;
...&lt;br /&gt;
    GenericVisualization  mSignalVis;&lt;br /&gt;
};&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;GenericVisualization&amp;lt;/tt&amp;gt;&#039;s constructor takes a one-byte&lt;br /&gt;
visualization&lt;br /&gt;
ID as a parameter; we need to get a unique ID in order to get our data&lt;br /&gt;
routed&lt;br /&gt;
to the correct operator window.&lt;br /&gt;
This can be done by adding an entry&lt;br /&gt;
&amp;lt;tt&amp;gt;LowPass&amp;lt;/tt&amp;gt; at the end of the &amp;lt;tt&amp;gt;SOURCEID&amp;lt;/tt&amp;gt; enumeration in&lt;br /&gt;
the file&lt;br /&gt;
&amp;lt;tt&amp;gt;shared/defines.h&amp;lt;/tt&amp;gt;.&lt;br /&gt;
Then, in our &amp;lt;tt&amp;gt;.cpp&amp;lt;/tt&amp;gt; file, we add&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;quot;defines.h&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
and change the &amp;lt;tt&amp;gt;LPFilter&amp;lt;/tt&amp;gt; constructor to read&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
LPFilter::LPFilter()&lt;br /&gt;
: mDecayFactor( 0 ),&lt;br /&gt;
  mPreviousOutput( 0 ),&lt;br /&gt;
  mSignalVis( SOURCEID::LowPass )&lt;br /&gt;
{&lt;br /&gt;
  BEGIN_PARAMETER_DEFINITIONS&lt;br /&gt;
    &amp;quot;Filtering float LPTimeConstant= 16s&amp;quot;&lt;br /&gt;
      &amp;quot; 16s 0 0 // time constant for the low pass filter in blocks or&lt;br /&gt;
      seconds&amp;quot;,&lt;br /&gt;
    &amp;quot;Visualize int VisualizeLowPass= 1&amp;quot;&lt;br /&gt;
      &amp;quot; 1 0 1 // visualize low pass output signal (0=no, 1=yes)&amp;quot;,&lt;br /&gt;
    &amp;quot;Visualize int LPVisMin= -100 0 0 0 &amp;quot;&lt;br /&gt;
      &amp;quot;// low pass visualization min value&amp;quot;,&lt;br /&gt;
    &amp;quot;Visualize int LPVisMax= 100 0 0 0 &amp;quot;&lt;br /&gt;
      &amp;quot;// low pass visualization max value&amp;quot;,&lt;br /&gt;
  END_PARAMETER_DEFINITIONS&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
where LPVisMin and LPVisMax parameters determine the default scaling&lt;br /&gt;
of the&lt;br /&gt;
displayed signal; these parameters may even be reversed, resulting in&lt;br /&gt;
an inversion&lt;br /&gt;
of the displayed signal, so there is no need to check these parameters&lt;br /&gt;
from&lt;br /&gt;
&amp;lt;tt&amp;gt;Preflight&amp;lt;/tt&amp;gt;.&lt;br /&gt;
In &amp;lt;tt&amp;gt;Initialize&amp;lt;/tt&amp;gt;, we add&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  mSignalVis.Send( CFGID::WINDOWTITLE, &amp;quot;Low Pass&amp;quot; );&lt;br /&gt;
  mSignalVis.Send( CFGID::graphType, CFGID::polyline );&lt;br /&gt;
  mSignalVis.Send( CFGID::MINVALUE, Parameter( &amp;quot;LPVisMin&amp;quot; ) );&lt;br /&gt;
  mSignalVis.Send( CFGID::MAXVALUE, Parameter( &amp;quot;LPVisMax&amp;quot; ) );&lt;br /&gt;
  mSignalVis.Send( CFGID::NUMSAMPLES, 2 * Parameter( &amp;quot;SamplingRate&amp;quot; ) );&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Finally, to update the display in regular intervals, we add the&lt;br /&gt;
following at the&lt;br /&gt;
end of &amp;lt;tt&amp;gt;Process&amp;lt;/tt&amp;gt;:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  if( Parameter( &amp;quot;VisualizeLowPass&amp;quot; ) == 1 )&lt;br /&gt;
    mSignalVis.Send( output );&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
We might also send data to the already existing task log memo window,&lt;br /&gt;
adding&lt;br /&gt;
another member&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  GenericVisualization  mTaskLogVis;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
initializing it with&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
LPFilter::LPFilter()&lt;br /&gt;
: ...&lt;br /&gt;
  mTaskLogVis( SOURCEID::TASKLOG )&lt;br /&gt;
{&lt;br /&gt;
 ...&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
and, from inside &amp;lt;tt&amp;gt;Process&amp;lt;/tt&amp;gt;, writing some text to it as in&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  if( ( *output )( 0, 0 ) &amp;gt; 10 )&lt;br /&gt;
  {&lt;br /&gt;
    ostringstream oss;&lt;br /&gt;
    oss &amp;lt;&amp;lt; &amp;quot;LPFilter: (0,0) entry of output exceeds 10 and is &amp;quot;&lt;br /&gt;
        &amp;lt;&amp;lt; ( *output )( 0, 0 );&lt;br /&gt;
    mTaskLogVis.Send( oss.str() );&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>Atennissen</name></author>
	</entry>
	<entry>
		<id>https://www.bci2000.org/mediawiki/index.php?title=P300_Off-line_Analysis_Tutorial&amp;diff=1792</id>
		<title>P300 Off-line Analysis Tutorial</title>
		<link rel="alternate" type="text/html" href="https://www.bci2000.org/mediawiki/index.php?title=P300_Off-line_Analysis_Tutorial&amp;diff=1792"/>
		<updated>2007-05-22T15:38:09Z</updated>

		<summary type="html">&lt;p&gt;Atennissen: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Starting an Analysis Session==&lt;br /&gt;
Every recording session has its own history. It is very difficult to say in advance what might happen during the recording. So we will assume that everything was perfect (the subject collaborated, no channel went lost, etc); later on we will consider the main causes of contamination, how to recognize it and what to do. &lt;br /&gt;
&lt;br /&gt;
If the recording session runs smoothly, you should now have eight files named TestSubjS001R01.dat to TestSubjS001R08.dat, in the folder c:\bci2000\data\Mu\TestSubj, corresponding to the eight runs, respectively. &lt;br /&gt;
&lt;br /&gt;
Before you start the analysis you should locate, on your hard disk, the correct montage file. This is a file that describes the list of channels that were acquired. In this tutorial we will use OneAndOnly_16ch.eloc.txt, which is located in the folder C:\BCI2000\Tutorial\Montages\. If you need to edit the *.mmf file, check its data format. &lt;br /&gt;
&lt;br /&gt;
==Opening Files with Mario==&lt;br /&gt;
After having run mario.exe, press &amp;quot;Select Data Files&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
[[Image:P300_1.jpg]]&lt;br /&gt;
&lt;br /&gt;
A dialog window will ask you to select the dat files. You can either select a single data file, or select multiple files. This time, we will select all files in the dataset. &lt;br /&gt;
&lt;br /&gt;
A green box will surround the Raw Data box in the main window. &lt;br /&gt;
&lt;br /&gt;
As an optional (but recommended) operation, click on the LOAD MONTAGE button and choose the mmf file. This will allow you to see the labels of each channel and allow you to apply spatial filters that depend on the electrode position. &lt;br /&gt;
&lt;br /&gt;
You can load an additional parameter file with choices different from those used in the experiment. &lt;br /&gt;
&lt;br /&gt;
At this point, you can check that P300 is selected in the Analysis menu (indicating that a P300 dataset has been recognized) and select the LOAD DATA button to confirm your choices. This will enable the EDIT CHANNEL LIST button that you can use to select the channels you want to include in your analysis.&lt;br /&gt;
&lt;br /&gt;
==Selecting Channels==&lt;br /&gt;
&lt;br /&gt;
When you select the EDIT CHANNEL LIST button, two forms will show you the channel list (valid ones and not-valid ones) and an image showing valid channels and their location. &lt;br /&gt;
&lt;br /&gt;
Clicking on Add and Remove buttons allows you to move a channel from one list to the other enabling or disabling it. &lt;br /&gt;
&lt;br /&gt;
==Selecting the Spatial Filter ==&lt;br /&gt;
&lt;br /&gt;
Return to the main window to choose which filter to apply for your analysis, selecting from the following filter choices: &lt;br /&gt;
&lt;br /&gt;
*RAW&lt;br /&gt;
*CAR&lt;br /&gt;
*Large Laplacian &lt;br /&gt;
*Small Laplacian &lt;br /&gt;
&lt;br /&gt;
Common Average Reference (CAR) will be fine for most of the situations. &lt;br /&gt;
&lt;br /&gt;
We hope soon, to release a user defined solution for any custom analysis. &lt;br /&gt;
&lt;br /&gt;
==Feature Extraction Analysis==&lt;br /&gt;
The Analysis field in the Feature Extraction panel will appear automatically depending on the files loaded, while the Feature Extractor field shows the only currently possible choice. &lt;br /&gt;
&lt;br /&gt;
You can view/edit analysis details by clicking &amp;quot;Set Analysis Details&amp;quot;&lt;br /&gt;
&lt;br /&gt;
[[Image:P300_2.jpg]]&lt;br /&gt;
&lt;br /&gt;
This form reports all the remaining settings for the P300 analysis. Most of the values are set as default values. With settings such as the ones reported in figure, the analysis software will: &lt;br /&gt;
&lt;br /&gt;
*sample the spectrum at points starting from 0.1 Hz to 15 Hz&lt;br /&gt;
*take a 650 ms long epoch of data.&lt;br /&gt;
&lt;br /&gt;
You can modify these settings according to your aims. When you are finished, remember to confirm your choices by clicking on DONE. It will make the program accept changes. &lt;br /&gt;
&lt;br /&gt;
At this point you can start the analysis by pressing the Evaluate and Plot button.&lt;br /&gt;
&lt;br /&gt;
[[Image:P300_3.jpg]]&lt;br /&gt;
&lt;br /&gt;
==View results==&lt;br /&gt;
The first figure that appears is the R-square matrix (channels x elapsed time after stimulus)&lt;br /&gt;
&lt;br /&gt;
===R-square Matrix===&lt;br /&gt;
The r-square matrix highlights the most relevant ERP features for the separation of potentials due to frequent or rare stimuli.&lt;br /&gt;
&lt;br /&gt;
[[Image:P300_4.jpg]]&lt;br /&gt;
&lt;br /&gt;
Each row of the matrix is related to a single channel, while a column represents a fixed latency. The color codes the statistical significance of the difference between the two kinds of evoked potentials. &lt;br /&gt;
&lt;br /&gt;
Thus a red color would mean that the ERP consequent to a rare stimulus is significantly more positive than the ERP consequent to a frequent stimulus.&lt;br /&gt;
&lt;br /&gt;
This figure is independent of the channel and latency settings that were set in the parameter dialog (since it summarizes all results). &lt;br /&gt;
&lt;br /&gt;
Clicking on the matrix will modify the channel/latency settings for the other figures; in fact the cell of the matrix that was clicked is characterized by one channel and one latency, whose waveform and topography (respectively) will be shown in the other two figures.&lt;br /&gt;
&lt;br /&gt;
You can choose whether to overwrite or to put the most recently evoked figures beside the previous one. Two sets of waveform/topography figures are available, and are linked to the click of the left or right mouse button.&lt;br /&gt;
&lt;br /&gt;
Clicking on any point of map will open four more windows: &lt;br /&gt;
&lt;br /&gt;
*Amplitude waveforms at selected channel(s) &lt;br /&gt;
*Topographic plots at selected latency(ies) &lt;br /&gt;
*ERP response to each stimulus &lt;br /&gt;
*An off-line prediction of the string read&lt;br /&gt;
&lt;br /&gt;
===Amplitude Waveform===&lt;br /&gt;
The whole timecourse of ERPs generated are displayed in the top panel, regardless of the specific stimulus (line of letters) that generated it. Rare ERPs are plotted in solid lines, while frequent ERPs are dotted. If two channels were selected in the P300 parameter dialog, they are plotted in red and in blue, respectively.&lt;br /&gt;
&lt;br /&gt;
[[Image:P300_5.jpg]]&lt;br /&gt;
&lt;br /&gt;
The bottom panel shows the r-square time course. It is roughly proportional to the difference between rare and frequent ERPs, but since r-square is sensitive to the dispersion (variance) of single trials, small differences in amplitude can result in a high r-square, if they are very reproducible.&lt;br /&gt;
&lt;br /&gt;
Topographic plots. This figure represents the scalp distribution of the r-square.&lt;br /&gt;
&lt;br /&gt;
[[Image:P300_6.jpg]]&lt;br /&gt;
&lt;br /&gt;
The color coding is the same as the r-square matrix figure, and values on each channel are interpolated to create a continuous bidimensional map. The higher the number of electrodes, the more accurate is the map. With Surface Laplacian spatial filteriing, the number of channels shown on the scalp may not coincide with the whole number of electrodes, since the value of the laplacian is not computed on the border channels.&lt;br /&gt;
&lt;br /&gt;
===ERP Response===&lt;br /&gt;
&lt;br /&gt;
[[Image:P300_7.jpg]]&lt;br /&gt;
&lt;br /&gt;
The figure shows the medium temporal course for the 12 stimuli. Red graphs are rare events while blue ones are frequent events.&lt;br /&gt;
&lt;br /&gt;
===String Prediction===&lt;br /&gt;
Mario also allows you to check the word that the BCI2000 system would have predicted if the current feature was used online.&lt;br /&gt;
&lt;br /&gt;
[[Image:P300_8.jpg]]&lt;br /&gt;
&lt;br /&gt;
In this example, since the sequence should have been SPELLWITHBCI, only 4 characters out of 12 (33%) have been correctly predicted. This score is well above chance, though quite inefficient.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{| border=&amp;quot;3&amp;quot; cellspacing=&amp;quot;5&amp;quot; cellpadding=&amp;quot;20&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
|S&lt;br /&gt;
|P&lt;br /&gt;
|E&lt;br /&gt;
|L&lt;br /&gt;
|L&lt;br /&gt;
|W&lt;br /&gt;
|I&lt;br /&gt;
|T&lt;br /&gt;
|H&lt;br /&gt;
|B&lt;br /&gt;
|C&lt;br /&gt;
|I&lt;br /&gt;
|- &lt;br /&gt;
|style=&amp;quot;background:#ff3322&amp;quot; |4&lt;br /&gt;
|style=&amp;quot;background:#ff3322&amp;quot; |M&lt;br /&gt;
|E&lt;br /&gt;
|L&lt;br /&gt;
|L&lt;br /&gt;
|style=&amp;quot;background:#ff3322&amp;quot; |4&lt;br /&gt;
|style=&amp;quot;background:#ff3322&amp;quot; |_&lt;br /&gt;
|T&lt;br /&gt;
|style=&amp;quot;background:#ff3322&amp;quot; |A&lt;br /&gt;
|style=&amp;quot;background:#ff3322&amp;quot; |K&lt;br /&gt;
|style=&amp;quot;background:#ff3322&amp;quot; |G&lt;br /&gt;
|style=&amp;quot;background:#ff3322&amp;quot; |4&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In summary, we must select the latency and the channel where the maxima of an ERP component, whose spatio-temporal shape is compatible with the P300 phenomenon, occurs. Testing the speller can suggest which component has the highest probability to predict the user&#039;s selected letter.&lt;/div&gt;</summary>
		<author><name>Atennissen</name></author>
	</entry>
	<entry>
		<id>https://www.bci2000.org/mediawiki/index.php?title=P300_Off-line_Analysis_Tutorial&amp;diff=1788</id>
		<title>P300 Off-line Analysis Tutorial</title>
		<link rel="alternate" type="text/html" href="https://www.bci2000.org/mediawiki/index.php?title=P300_Off-line_Analysis_Tutorial&amp;diff=1788"/>
		<updated>2007-05-10T20:32:36Z</updated>

		<summary type="html">&lt;p&gt;Atennissen: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Starting an Analysis Session==&lt;br /&gt;
Every recording session has its own history. It is very difficult to say in advance what might happen during the recording. So we will assume that everything was perfect (the subject collaborated, no channel went lost, etc); later on we will consider the main causes of contamination, how to recognize it and what to do. &lt;br /&gt;
&lt;br /&gt;
If the recording session runs smoothly, you should now have eight files named TestSubjS001R01.dat to TestSubjS001R08.dat, in the folder c:\bci2000\data\Mu\TestSubj, corresponding to the eight runs, respectively. &lt;br /&gt;
&lt;br /&gt;
Before you start the analysis you should locate on your hard disk the correct montage file on your hard disk. This is a file that describes the list of channels that were acquired. In this tutorial we will use OneAndOnly_16ch.eloc.txt, which is located in the folder C:\BCI2000\Tutorial\Montages\. If you need to edit the *.mmf file, check its data format. &lt;br /&gt;
&lt;br /&gt;
==Opening Files with Mario==&lt;br /&gt;
After having run mario.exe, press &amp;quot;Select Data Files&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
[[Image:P300_1.jpg]]&lt;br /&gt;
&lt;br /&gt;
A dialog window will ask you to select the dat files. You can either select a single data file, or select multiple files. This time, we will select all files in the dataset. &lt;br /&gt;
&lt;br /&gt;
A green box will surround the Raw Data box in the main window. &lt;br /&gt;
&lt;br /&gt;
As an optional (but recommended) operation, click on the LOAD MONTAGE button and choose the mmf file. This will allow you to see the labels of each channel and allow you to apply spatial filters that depend on the electrode position. &lt;br /&gt;
&lt;br /&gt;
You can load an additional parameter file with choices different from those used in the experiment. &lt;br /&gt;
&lt;br /&gt;
At this point, you can check that P300 is selected in the Analysis menu (indicating that a P300 dataset has been recognized) and select the LOAD DATA button to confirm your choices. This will enable the EDIT CHANNEL LIST button that you can use to select the channels you want to include in your analysis.&lt;br /&gt;
&lt;br /&gt;
==Selecting Channels==&lt;br /&gt;
&lt;br /&gt;
When you select the EDIT CHANNEL LIST button, two forms will show you the channel list (valid ones and not-valid ones) and an image showing valid channels and their location. &lt;br /&gt;
&lt;br /&gt;
Clicking on Add and Remove buttons allows you to move a channel from one list to the other enabling or disabling it. &lt;br /&gt;
&lt;br /&gt;
==Selecting the Spatial Filter ==&lt;br /&gt;
&lt;br /&gt;
Return to the main window and you can choose which filter to apply for your analyses, selecting from the following filter choices: &lt;br /&gt;
&lt;br /&gt;
*RAW&lt;br /&gt;
*CAR&lt;br /&gt;
*Large Laplacian &lt;br /&gt;
*Small Laplacian &lt;br /&gt;
&lt;br /&gt;
Common Average Reference (CAR) will be fine for most of the situations. &lt;br /&gt;
&lt;br /&gt;
We hope soon, to release soon a user defined solution for any custom analysis. &lt;br /&gt;
&lt;br /&gt;
==Feature Extraction Analysis==&lt;br /&gt;
The Analysis field in the Feature Extraction panel will appear automatically according to the files loaded while the Feature Extractor field shows the only currently possible choice. &lt;br /&gt;
&lt;br /&gt;
You can view/edit analysis details by clicking &amp;quot;Set Analysis Details&amp;quot;&lt;br /&gt;
&lt;br /&gt;
[[Image:P300_2.jpg]]&lt;br /&gt;
&lt;br /&gt;
This form reports all the remaining settings for the P300 analysis. Most of the values are set as default values. With settings such as the ones reported in figure, the analysis software will: &lt;br /&gt;
&lt;br /&gt;
*sample the spectrum at points starting from 0.1 Hz to 15 Hz;&lt;br /&gt;
*take a 650 ms long epoch of data.&lt;br /&gt;
&lt;br /&gt;
You can modify these settings according to your aims. When you are finished, remember to confirm your choices by clicking on DONE. It will make the program accept changes. &lt;br /&gt;
&lt;br /&gt;
At this point you can start the analysis by pressing the Evaluate and Plot button.&lt;br /&gt;
&lt;br /&gt;
[[Image:P300_3.jpg]]&lt;br /&gt;
&lt;br /&gt;
==View results==&lt;br /&gt;
The first figure that appears is the R-square matrix (channels x elapsed time after stimulus)&lt;br /&gt;
&lt;br /&gt;
===R-square Matrix===&lt;br /&gt;
The r-square matrix highlights the most relevant ERP features for the separation of potentials due to frequent or rare stimuli.&lt;br /&gt;
&lt;br /&gt;
[[Image:P300_4.jpg]]&lt;br /&gt;
&lt;br /&gt;
Each row of the matrix is related to a single channel, while a column represents a fixed latency. The color codes the statistical significance of the difference between the two kinds of evoked potentials. &lt;br /&gt;
&lt;br /&gt;
Thus a red color would mean that the ERP consequent to a rare stimulus is significantly more positive than the ERP consequent to a frequent stimulus.&lt;br /&gt;
&lt;br /&gt;
This figure is independent of the channel and latency settings that were set in the parameter dialog (since it summarizes all results). &lt;br /&gt;
&lt;br /&gt;
Clicking on the matrix will modify the channel/latency settings for the other figures; in fact the cell of the matrix that was clicked is characterized by one channel and one latency, whose waveform and topography (respectively) will be shown in the other two figures.&lt;br /&gt;
&lt;br /&gt;
You can choose whether to overwrite or to put the most recently evoked figures beside the previous one. Two sets of waveform/topography figures are available, and are linked to the click of the left or right mouse button.&lt;br /&gt;
&lt;br /&gt;
Clicking on any point of map will open four more windows: &lt;br /&gt;
&lt;br /&gt;
*Amplitude waveforms at selected channel(s) &lt;br /&gt;
*Topographic plots at selected latency(ies) &lt;br /&gt;
*ERP response to each stimulus &lt;br /&gt;
*An off-line prediction of the string read&lt;br /&gt;
&lt;br /&gt;
===Amplitude Waveform===&lt;br /&gt;
The whole timecourse of ERPs generated are displayed in the top panel, regardless of the specific stimulus (line of letters) that generated it. Rare ERPs are plotted in solid lines, while frequent ERPs are dotted. If two channels were selected in the P300 parameter dialog, they are plotted in red and in blue, respectively.&lt;br /&gt;
&lt;br /&gt;
[[Image:P300_5.jpg]]&lt;br /&gt;
&lt;br /&gt;
The bottom panel shows the r-square time course. It is roughly proportional to the difference between rare and frequent ERPs, but since r-square is sensitive to the dispersion (variance) of single trials, small differences in amplitude can result in a high r-square, if they are very reproducible.&lt;br /&gt;
&lt;br /&gt;
Topographic plots. This figure represents the scalp distribution of the r-square.&lt;br /&gt;
&lt;br /&gt;
[[Image:P300_6.jpg]]&lt;br /&gt;
&lt;br /&gt;
The color coding is the same as the r-square matrix figure, and values on each channel are interpolated to create a continuous bidimensional map. The higher the number of electrodes, the more accurate is the map. With Surface Laplacian spatial filteriing, the number of channels shown on the scalp may not coincide with the whole number of electrodes, since the value of the laplacian is not computed on the border channels.&lt;br /&gt;
&lt;br /&gt;
===ERP Response===&lt;br /&gt;
&lt;br /&gt;
[[Image:P300_7.jpg]]&lt;br /&gt;
&lt;br /&gt;
The figure shows the medium temporal course for the 12 stimuli. Red graphs are rare events while blue ones are frequent events.&lt;br /&gt;
&lt;br /&gt;
===String Prediction===&lt;br /&gt;
Mario also allows you to check the word that the BCI2000 system would have predicted if the current feature was used online.&lt;br /&gt;
&lt;br /&gt;
[[Image:P300_8.jpg]]&lt;br /&gt;
&lt;br /&gt;
In this example, since the sequence should have been SPELLWITHBCI, only 4 characters out of 12 (33%) have been correctly predicted. This score is well above chance, though quite inefficient.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{| border=&amp;quot;3&amp;quot; cellspacing=&amp;quot;5&amp;quot; cellpadding=&amp;quot;20&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
|S&lt;br /&gt;
|P&lt;br /&gt;
|E&lt;br /&gt;
|L&lt;br /&gt;
|L&lt;br /&gt;
|W&lt;br /&gt;
|I&lt;br /&gt;
|T&lt;br /&gt;
|H&lt;br /&gt;
|B&lt;br /&gt;
|C&lt;br /&gt;
|I&lt;br /&gt;
|- &lt;br /&gt;
|style=&amp;quot;background:#ff3322&amp;quot; |4&lt;br /&gt;
|style=&amp;quot;background:#ff3322&amp;quot; |M&lt;br /&gt;
|E&lt;br /&gt;
|L&lt;br /&gt;
|L&lt;br /&gt;
|style=&amp;quot;background:#ff3322&amp;quot; |4&lt;br /&gt;
|style=&amp;quot;background:#ff3322&amp;quot; |_&lt;br /&gt;
|T&lt;br /&gt;
|style=&amp;quot;background:#ff3322&amp;quot; |A&lt;br /&gt;
|style=&amp;quot;background:#ff3322&amp;quot; |K&lt;br /&gt;
|style=&amp;quot;background:#ff3322&amp;quot; |G&lt;br /&gt;
|style=&amp;quot;background:#ff3322&amp;quot; |4&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In summary, we must select the latency and the channel where the maxima of an ERP component whose spatio-temporal shape is compatible with the P300 phenomenon occurs. Testing the speller can suggest which component has the highest probability to predict the user&#039;s selected letter.&lt;/div&gt;</summary>
		<author><name>Atennissen</name></author>
	</entry>
	<entry>
		<id>https://www.bci2000.org/mediawiki/index.php?title=P300_Off-line_Analysis_Tutorial&amp;diff=1787</id>
		<title>P300 Off-line Analysis Tutorial</title>
		<link rel="alternate" type="text/html" href="https://www.bci2000.org/mediawiki/index.php?title=P300_Off-line_Analysis_Tutorial&amp;diff=1787"/>
		<updated>2007-05-10T20:25:17Z</updated>

		<summary type="html">&lt;p&gt;Atennissen: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Starting an Analysis Session==&lt;br /&gt;
Every recording session has its own history. It is very difficult to say in advance what might happen during the recording. So we will assume that everything was perfect (the subject collaborated, no channel went lost, etc); later on we will consider the main causes of contamination, how to recognize it and what to do. &lt;br /&gt;
&lt;br /&gt;
If the recording session runs smoothly, you should now have eight files named TestSubjS001R01.dat to TestSubjS001R08.dat, in the folder c:\bci2000\data\Mu\TestSubj, corresponding to the eight runs, respectively. &lt;br /&gt;
&lt;br /&gt;
Before you start the analysis you should locate on your hard disk the correct montage file on your hard disk. This is a file that describes the list of channels that were acquired. In this tutorial we will use OneAndOnly_16ch.eloc.txt, which is located in the folder C:\BCI2000\Tutorial\Montages\. If you need to edit the *.mmf file, check its data format. &lt;br /&gt;
&lt;br /&gt;
==Opening Files with Mario==&lt;br /&gt;
After having run mario.exe, press &amp;quot;Select Data Files&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
[[Image:P300_1.jpg]]&lt;br /&gt;
&lt;br /&gt;
A dialog window will ask you to select the dat files. You can either select a single data file, or select multiple files. This time, we will select all files in the dataset. &lt;br /&gt;
&lt;br /&gt;
A green box will surround the Raw Data box in the main window. &lt;br /&gt;
&lt;br /&gt;
As an optional (but recommended) operation, click on the LOAD MONTAGE button and choose the mmf file. This will allow you to see the labels of each channel and allow you to apply spatial filters that depend on the electrode position. &lt;br /&gt;
&lt;br /&gt;
You can load an additional parameter file with choices different from those used in the experiment. &lt;br /&gt;
&lt;br /&gt;
At this point, you can check that P300 is selected in the Analysis menu (indicating that a P300 dataset has been recognized) and select the LOAD DATA button to confirm your choices. This will enable the EDIT CHANNEL LIST button that you can use to select the channels you want to include in your analysis.&lt;br /&gt;
&lt;br /&gt;
==Selecting Channels==&lt;br /&gt;
&lt;br /&gt;
When you select the EDIT CHANNEL LIST button, two forms will show you the channel list (valid ones and not-valid ones) and an image showing valid channels and their location. &lt;br /&gt;
&lt;br /&gt;
Clicking on Add and Remove buttons allows you to move a channel from one list to the other enabling or disabling it. &lt;br /&gt;
&lt;br /&gt;
==Selecting the Spatial Filter ==&lt;br /&gt;
&lt;br /&gt;
Return to the main window and you can choose which filter to apply for your analyses, selecting from the following filter choices: &lt;br /&gt;
&lt;br /&gt;
*RAW&lt;br /&gt;
*CAR&lt;br /&gt;
*Large Laplacian &lt;br /&gt;
*Small Laplacian &lt;br /&gt;
&lt;br /&gt;
Common Average Reference (CAR) will be fine for most of the situations. &lt;br /&gt;
&lt;br /&gt;
We hope soon, to release soon a user defined solution for any custom analysis. &lt;br /&gt;
&lt;br /&gt;
==Feature Extraction Analysis==&lt;br /&gt;
The Analysis field in the Feature Extraction panel will appear automatically according to the files loaded while the Feature Extractor field shows the only currently possible choice. &lt;br /&gt;
&lt;br /&gt;
You can view/edit analysis details by clicking &amp;quot;Set Analysis Details&amp;quot;&lt;br /&gt;
&lt;br /&gt;
[[Image:P300_2.jpg]]&lt;br /&gt;
&lt;br /&gt;
This form reports all the remaining settings for the P300 analysis. Most of the values are set as default values. With settings such as the ones reported in figure, the analysis software will: &lt;br /&gt;
&lt;br /&gt;
*sample the spectrum at points starting from 0.1 Hz to 15 Hz;&lt;br /&gt;
*take a 650 ms long epoch of data.&lt;br /&gt;
&lt;br /&gt;
You can modify these settings according to your aims. When you are finished, remember to confirm your choices by clicking on DONE. It will make the program accept changes. &lt;br /&gt;
&lt;br /&gt;
At this point you can start the analysis by pressing the Evaluate and Plot button.&lt;br /&gt;
&lt;br /&gt;
[[Image:P300_3.jpg]]&lt;br /&gt;
&lt;br /&gt;
==View results==&lt;br /&gt;
The first figure that appears is the R-square matrix (channels x elapsed time after stimulus)&lt;br /&gt;
&lt;br /&gt;
===R-square Matrix===&lt;br /&gt;
The r-square matrix highlights the most relevant ERP features for the separation of potentials due to frequent or rare stimuli.&lt;br /&gt;
&lt;br /&gt;
[[Image:P300_4.jpg]]&lt;br /&gt;
&lt;br /&gt;
Each row of the matrix is related to a single channel, while a column represents a fixed latency. The color codes the statistical significance of the difference between the two kinds of evoked potentials. &lt;br /&gt;
&lt;br /&gt;
Thus a red color would mean that the ERP consequent to a rare stimulus is significantly more positive than the ERP consequent to a frequent stimulus.&lt;br /&gt;
&lt;br /&gt;
This figure is independent of the channel and latency settings that were set in the parameter dialog (since it summarizes all results). &lt;br /&gt;
&lt;br /&gt;
Clicking on the matrix will modify the channel/latency settings for the other figures; in fact the cell of the matrix that was clicked is characterized by one channel and one latency, whose waveform and topography (respectively) will be shown in the other two figures.&lt;br /&gt;
&lt;br /&gt;
You can choose whether to overwrite or to put the most recently evoked figures beside the previous one. Two sets of waveform/topography figures are available, and are linked to the click of the left or right mouse button.&lt;br /&gt;
&lt;br /&gt;
Clicking on any point of map will open four more windows: &lt;br /&gt;
&lt;br /&gt;
*Amplitude waveforms at selected channel(s) &lt;br /&gt;
*Topographic plots at selected latency(ies) &lt;br /&gt;
*ERP response to each stimulus &lt;br /&gt;
*An off-line prediction of the string read&lt;br /&gt;
&lt;br /&gt;
===Amplitude Waveform===&lt;br /&gt;
The whole timecourse of ERPs generated are displayed in the top panel, regardless of the specific stimulus (line of letters) that generated it. Rare ERPs are plotted in solid lines, while frequent ERPs are dotted. If two channels were selected in the P300 parameter dialog, they are plotted in red and in blue, respectively.&lt;br /&gt;
&lt;br /&gt;
[[Image:P300_5.jpg]]&lt;br /&gt;
&lt;br /&gt;
The bottom panel shows the r-square time course. It is roughly proportional to the difference between rare and frequent ERPs, but since r-square is sensitive to the dispersion (variance) of single trials, small differences in amplitude can result in a high r-square, if they are very reproducible.&lt;br /&gt;
&lt;br /&gt;
Topographic plots. This figure represents the scalp distribution of the r-square.&lt;br /&gt;
&lt;br /&gt;
[[Image:P300_6.jpg]]&lt;br /&gt;
&lt;br /&gt;
The color coding is the same as the r-square matrix figure, and values on each channel are interpolated to create a continuous bidimensional map. The higher the number of electrodes, the more accurate is the map. With Surface Laplacian spatial filteriing, the number of channels shown on the scalp may not coincide with the whole number of electrodes, since the value of the laplacian is not computed on the border channels.&lt;br /&gt;
&lt;br /&gt;
===ERP Response===&lt;br /&gt;
&lt;br /&gt;
[[Image:P300_7.jpg]]&lt;br /&gt;
&lt;br /&gt;
The figure shows the medium temporal course for the 12 stimuli. Red graphs are rare events while blue ones are frequent events.&lt;br /&gt;
&lt;br /&gt;
===String Prediction===&lt;br /&gt;
Mario also allows to check what is the word that the BCI2000 system would have predicted if the current feature was used online.&lt;br /&gt;
&lt;br /&gt;
[[Image:P300_8.jpg]]&lt;br /&gt;
&lt;br /&gt;
In the case in example, since the sequence should have been SPELLWITHBCI, only 4 characters out of 12 (33%) have been correctly predicted. This score is well above chance, though quite inefficient.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{| border=&amp;quot;3&amp;quot; cellspacing=&amp;quot;5&amp;quot; cellpadding=&amp;quot;20&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
|S&lt;br /&gt;
|P&lt;br /&gt;
|E&lt;br /&gt;
|L&lt;br /&gt;
|L&lt;br /&gt;
|W&lt;br /&gt;
|I&lt;br /&gt;
|T&lt;br /&gt;
|H&lt;br /&gt;
|B&lt;br /&gt;
|C&lt;br /&gt;
|I&lt;br /&gt;
|- &lt;br /&gt;
|style=&amp;quot;background:#ff3322&amp;quot; |4&lt;br /&gt;
|style=&amp;quot;background:#ff3322&amp;quot; |M&lt;br /&gt;
|E&lt;br /&gt;
|L&lt;br /&gt;
|L&lt;br /&gt;
|style=&amp;quot;background:#ff3322&amp;quot; |4&lt;br /&gt;
|style=&amp;quot;background:#ff3322&amp;quot; |_&lt;br /&gt;
|T&lt;br /&gt;
|style=&amp;quot;background:#ff3322&amp;quot; |A&lt;br /&gt;
|style=&amp;quot;background:#ff3322&amp;quot; |K&lt;br /&gt;
|style=&amp;quot;background:#ff3322&amp;quot; |G&lt;br /&gt;
|style=&amp;quot;background:#ff3322&amp;quot; |4&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In summary, we must select the latency and the channel where the maxima occurs of a ERP component whose spatio-temporal shape is compatible with the P300 phenomenon. Testing the speller can suggest which component has the highest probability to predict the user&#039;s selected letter.&lt;/div&gt;</summary>
		<author><name>Atennissen</name></author>
	</entry>
	<entry>
		<id>https://www.bci2000.org/mediawiki/index.php?title=Programming_Tutorial:Implementing_a_Source_Module&amp;diff=1786</id>
		<title>Programming Tutorial:Implementing a Source Module</title>
		<link rel="alternate" type="text/html" href="https://www.bci2000.org/mediawiki/index.php?title=Programming_Tutorial:Implementing_a_Source_Module&amp;diff=1786"/>
		<updated>2007-05-10T19:48:58Z</updated>

		<summary type="html">&lt;p&gt;Atennissen: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Data acquisition modules are factored into code required for any&lt;br /&gt;
hardware,&lt;br /&gt;
and code required to access a specific hardware.&lt;br /&gt;
You provide a function that waits for and reads A/D&lt;br /&gt;
data (line 3 in the EEG source pseudo code of [[Modules:Data Acquisition]]),&lt;br /&gt;
together with some helper functions that perform initialization and&lt;br /&gt;
cleanup tasks.&lt;br /&gt;
Together these functions form a class derived from&lt;br /&gt;
&amp;lt;tt&amp;gt;GenericADC&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==Scenario==&lt;br /&gt;
Your &#039;&#039;Tachyon Corporation&#039;&#039;  A/D card comes with a C-style&lt;br /&gt;
software interface&lt;br /&gt;
declared in a header file &amp;lt;tt&amp;gt;&amp;quot;TachyonLib.h&amp;quot;&amp;lt;/tt&amp;gt; that consists of&lt;br /&gt;
three&lt;br /&gt;
functions&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#define TACHYON_NO_ERROR 0&lt;br /&gt;
int TachyonStart( int inSamplingRate, int inNumberOfChannels );&lt;br /&gt;
int TachyonStop( void );&lt;br /&gt;
int TachyonWaitForData( short** outBuffer, int inCount );&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
From the library help file, you learn that &amp;lt;tt&amp;gt;TachyonStart&amp;lt;/tt&amp;gt;&lt;br /&gt;
configures the&lt;br /&gt;
card and starts acquisition to some internal buffer; that&lt;br /&gt;
&amp;lt;tt&amp;gt;TachyonStop&amp;lt;/tt&amp;gt;&lt;br /&gt;
stops acquisition to the buffer, and that &amp;lt;tt&amp;gt;TachyonWaitForData&amp;lt;/tt&amp;gt;&lt;br /&gt;
will block execution until the specified amount of data has been&lt;br /&gt;
acquired, and&lt;br /&gt;
that it will return a pointer to a buffer containing the data in its&lt;br /&gt;
first argument.&lt;br /&gt;
Each of the functions will return zero if everything went well, otherwise&lt;br /&gt;
some error value will be given.&lt;br /&gt;
Luckily, &#039;&#039;Tachyon Corporation&#039;&#039;  gives you just&lt;br /&gt;
what you need for a BCI2000 source module, so implementing the ADC&lt;br /&gt;
class is&lt;br /&gt;
quite straightforward.&lt;br /&gt;
&lt;br /&gt;
==Writing the ADC Header File==&lt;br /&gt;
In your class&#039; header file, &amp;lt;tt&amp;gt;&amp;quot;TachyonADC.h&amp;quot;&amp;lt;/tt&amp;gt;, you write&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#ifndef TACHYON_ADC_H&lt;br /&gt;
#define TACHYON_ADC_H&lt;br /&gt;
&lt;br /&gt;
#include &amp;quot;GenericADC.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
class TachyonADC : public GenericADC&lt;br /&gt;
{&lt;br /&gt;
 public:&lt;br /&gt;
   TachyonADC();&lt;br /&gt;
   ~TachyonADC();&lt;br /&gt;
&lt;br /&gt;
   void Preflight( const SignalProperties&amp;amp;, SignalProperties&amp;amp; ) const;&lt;br /&gt;
   void Initialize();&lt;br /&gt;
   void Process( const GenericSignal*, GenericSignal* );&lt;br /&gt;
   void Halt();&lt;br /&gt;
&lt;br /&gt;
 private:&lt;br /&gt;
   int  mSourceCh,&lt;br /&gt;
        mSampleBlockSize,&lt;br /&gt;
        mSamplingRate;&lt;br /&gt;
};&lt;br /&gt;
#endif // TACHYON_ADC_H&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==ADC Implementation==&lt;br /&gt;
In the .cpp file, you will need some &amp;lt;tt&amp;gt;#includes&amp;lt;/tt&amp;gt;, and a filter&lt;br /&gt;
registration:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;quot;TachyonADC.h&amp;quot;&lt;br /&gt;
#include &amp;quot;Tachyon/TachyonLib.h&amp;quot;&lt;br /&gt;
#include &amp;quot;BCIError.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
using namespace std;&lt;br /&gt;
&lt;br /&gt;
RegisterFilter( TachyonADC, 1 );&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
From the constructor, you request parameters and states that your ADC&lt;br /&gt;
needs;&lt;br /&gt;
from the destructor, you call &amp;lt;tt&amp;gt;Halt&amp;lt;/tt&amp;gt; to make sure that your&lt;br /&gt;
board stops&lt;br /&gt;
acquiring data whenever your class instance gets destructed:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
TachyonADC::TachyonADC()&lt;br /&gt;
: mSourceCh( 0 ),&lt;br /&gt;
  mSampleBlockSize( 0 ),&lt;br /&gt;
  mSamplingRate( 0 )&lt;br /&gt;
{&lt;br /&gt;
  BEGIN_PARAMETER_DEFINITIONS&lt;br /&gt;
    &amp;quot;Source int SourceCh=        64 64 1 128 &amp;quot;&lt;br /&gt;
        &amp;quot;// this is the number of digitized channels&amp;quot;,&lt;br /&gt;
    &amp;quot;Source int SampleBlockSize= 16 5 1 128 &amp;quot;&lt;br /&gt;
        &amp;quot;// this is the number of samples transmitted at a time&amp;quot;,&lt;br /&gt;
    &amp;quot;Source int SamplingRate=    128 128 1 4000 &amp;quot;&lt;br /&gt;
        &amp;quot;// this is the sample rate&amp;quot;,&lt;br /&gt;
  END_PARAMETER_DEFINITIONS&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
TachyonADC::~TachyonADC()&lt;br /&gt;
{&lt;br /&gt;
  Halt();&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==ADC Initialization==&lt;br /&gt;
Your &amp;lt;tt&amp;gt;Preflight&amp;lt;/tt&amp;gt; function will check whether the board works&lt;br /&gt;
with the&lt;br /&gt;
parameters requested, and communicate the dimensions of its output&lt;br /&gt;
signal:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void TachyonADC::Preflight( const SignalProperties&amp;amp;,&lt;br /&gt;
                              SignalProperties&amp;amp; outputProperties )&lt;br /&gt;
                              const&lt;br /&gt;
{&lt;br /&gt;
  if( TACHYON_NO_ERROR != &lt;br /&gt;
        TachyonStart( Parameter( &amp;quot;SamplingRate&amp;quot; ), Parameter( &amp;quot;SourceCh&amp;quot; ) ) )&lt;br /&gt;
    bcierr &amp;lt;&amp;lt; &amp;quot;SamplingRate and/or SourceCh parameters are not compatible&amp;quot;&lt;br /&gt;
           &amp;lt;&amp;lt; &amp;quot; with the A/D card&amp;quot;&lt;br /&gt;
           &amp;lt;&amp;lt; endl;&lt;br /&gt;
  TachyonStop();&lt;br /&gt;
  outputProperties = SignalProperties( Parameter( &amp;quot;SourceCh&amp;quot; ),&lt;br /&gt;
                          Parameter( &amp;quot;SampleBlockSize&amp;quot; ),&lt;br /&gt;
                          SignalType::int16 );&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Here, the last argument of the &amp;lt;tt&amp;gt;SignalProperties&amp;lt;/tt&amp;gt; constructor&lt;br /&gt;
determines not only the type of the signal propagated to the BCI2000&lt;br /&gt;
filters&lt;br /&gt;
but also the format of the &amp;lt;tt&amp;gt;dat&amp;lt;/tt&amp;gt; file written by the source&lt;br /&gt;
module.&lt;br /&gt;
For the &amp;lt;tt&amp;gt;Initialize&amp;lt;/tt&amp;gt; function, it will only be&lt;br /&gt;
called if&lt;br /&gt;
&amp;lt;tt&amp;gt;Preflight&amp;lt;/tt&amp;gt; did not report any errors. If everything works &lt;br /&gt;
fine with&lt;br /&gt;
the parameters, you may skip any checks, and write &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void TachyonADC::Initialize()&lt;br /&gt;
{&lt;br /&gt;
  mSourceCh = Parameter( &amp;quot;SourceCh&amp;quot; );&lt;br /&gt;
  mSampleBlockSize = Parameter( &amp;quot;SampleBlockSize&amp;quot; );&lt;br /&gt;
  mSamplingRate = Parameter( &amp;quot;SamplingRate&amp;quot; );&lt;br /&gt;
  TachyonStart( mSamplingRate, mSourceCh );&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Balancing the &amp;lt;tt&amp;gt;TachyonStart&amp;lt;/tt&amp;gt; call in the &amp;lt;tt&amp;gt;Initialize&amp;lt;/tt&amp;gt; function,&lt;br /&gt;
your &amp;lt;tt&amp;gt;Halt&amp;lt;/tt&amp;gt; function should stop all asynchronous activity that&lt;br /&gt;
your ADC code initiates:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void TachyonADC::Halt()&lt;br /&gt;
{&lt;br /&gt;
  TachyonStop();&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Data Acquisition==&lt;br /&gt;
Note that the function may not return unless the output signal is filled with data, so it is&lt;br /&gt;
crucial that &amp;lt;tt&amp;gt;TachyonWaitForData&amp;lt;/tt&amp;gt; is a blocking function.&lt;br /&gt;
(If your card does not provide such a function, and you need to poll&lt;br /&gt;
for data, don&#039;t forget to call &amp;lt;tt&amp;gt;Sleep( 0 )&amp;lt;/tt&amp;gt; inside your polling loop to&lt;br /&gt;
avoid tying up the CPU.)&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void TachyonADC::Process( const GenericSignal*, GenericSignal* outputSignal )&lt;br /&gt;
{&lt;br /&gt;
  int valuesToRead = mSampleBlockSize * mSourceCh;&lt;br /&gt;
  short* buffer;&lt;br /&gt;
  if( TACHYON_NO_ERROR == TachyonWaitForData( &amp;amp;buffer, valuesToRead ) )&lt;br /&gt;
  {&lt;br /&gt;
    int i = 0;&lt;br /&gt;
    for( int channel = 0; channel &amp;lt; mSourceCh; ++channel )&lt;br /&gt;
      for( int sample = 0; sample &amp;lt; mSampleBlockSize; ++sample )&lt;br /&gt;
        ( *outputSignal )( channel, sample ) = buffer[ i++ ];&lt;br /&gt;
  }&lt;br /&gt;
  else&lt;br /&gt;
    bcierr &amp;lt;&amp;lt; &amp;quot;Error reading data&amp;quot; &amp;lt;&amp;lt; endl;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Finished==&lt;br /&gt;
You are done! Use your &amp;lt;tt&amp;gt;TachyonADC.cpp&amp;lt;/tt&amp;gt; to replace the&lt;br /&gt;
&amp;lt;tt&amp;gt;GenericADC&amp;lt;/tt&amp;gt;&lt;br /&gt;
descendant in an existing source module, add the&lt;br /&gt;
&amp;lt;tt&amp;gt;TachyonADC.lib&amp;lt;/tt&amp;gt; shipped&lt;br /&gt;
with your card to the project, compile, link, and find the bugs...&lt;/div&gt;</summary>
		<author><name>Atennissen</name></author>
	</entry>
	<entry>
		<id>https://www.bci2000.org/mediawiki/index.php?title=Mu_Rhythm_Off-line_Analysis_Tutorial&amp;diff=1785</id>
		<title>Mu Rhythm Off-line Analysis Tutorial</title>
		<link rel="alternate" type="text/html" href="https://www.bci2000.org/mediawiki/index.php?title=Mu_Rhythm_Off-line_Analysis_Tutorial&amp;diff=1785"/>
		<updated>2007-05-10T19:47:24Z</updated>

		<summary type="html">&lt;p&gt;Atennissen: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Starting an Analysis Session ==&lt;br /&gt;
&lt;br /&gt;
Every recording session has its own history. It is very difficult to say in advance what might happen during the recording. So we will assume that everything was perfect (the subject collaborated, no channel went lost, etc); later on we will consider the main causes of contamination, how to recognize it and what to do.&lt;br /&gt;
&lt;br /&gt;
If the recording session runs smoothly, you should now have in the folder &#039;&#039;\TestData\Data\Mu&#039;&#039;,   two files named &#039;&#039;ALFAS006R01.dat&#039;&#039; and &#039;&#039;ALFAS006R02.dat&#039;&#039;, corresponding to two of the eight runs usually recorded, respectively.&lt;br /&gt;
&lt;br /&gt;
Before you start the analysis you should locate the correct montage file on your hard disk. This is a file that describes the list of channels that were acquired. In this tutorial we will use &#039;&#039;Complete_Montage(suggested choice).mmf&#039;&#039;, which is located in the folder &#039;&#039;\TestData\Montage&#039;&#039;. If you need to edit the *.mmf file, check its data format.&lt;br /&gt;
&lt;br /&gt;
== Opening Files with Mario ==&lt;br /&gt;
&lt;br /&gt;
After having run mario.exe, press &amp;quot;Select Data Files&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
[[Image:Mu Rhy5.jpg]]&lt;br /&gt;
&lt;br /&gt;
A dialog window will ask you to select the dat files. You can either select a single data file, or select multiple files. This time, we will select all files in the dataset.&lt;br /&gt;
&lt;br /&gt;
A green box will surround the Raw Data box in the main window.&lt;br /&gt;
&lt;br /&gt;
As an optional (but recommended) operation, click on the LOAD MONTAGE button and choose the mmf file. This will allow you to see the labels of each channel and allow you to apply spatial filters that depend on the electrode position.&lt;br /&gt;
&lt;br /&gt;
You can load an additional parameters file with choices different from those used during the experiment.&lt;br /&gt;
&lt;br /&gt;
At this point, you can check that Mu is selected in the Analysis menu (indicating that a Mu dataset has been recognized) and click on the LOAD DATA button to confirm your choices. This will enable the EDIT CHANNEL LIST button that you can use to select the channels you want to include in your analysis.&lt;br /&gt;
&lt;br /&gt;
== Selecting Channels ==&lt;br /&gt;
&lt;br /&gt;
When you select the EDIT CHANNEL LIST button, two forms will show you the channel list (valid ones and not-valid ones) and an image showing valid channels and their location.&lt;br /&gt;
&lt;br /&gt;
Clicking on Add and Remove buttons allows you to move a channel from one list to the other, enabling or disabling it.&lt;br /&gt;
&lt;br /&gt;
== Selecting the Spatial Filter ==&lt;br /&gt;
&lt;br /&gt;
Return to the main window, and you can choose which filter to apply for your analysis, selecting from the following filter choices:&lt;br /&gt;
&lt;br /&gt;
:*RAW&lt;br /&gt;
:*CAR&lt;br /&gt;
:*Large Laplacian&lt;br /&gt;
:*Small Laplacian&lt;br /&gt;
&lt;br /&gt;
Common Average Reference (CAR) will be fine for most of the situations.&lt;br /&gt;
&lt;br /&gt;
We hope, soon, to release a user defined solution for any custom analysis.&lt;br /&gt;
&lt;br /&gt;
== Feature Extraction Analysis ==&lt;br /&gt;
&lt;br /&gt;
The Analysis field in the Feature Extraction panel will appear automatically according to the files loaded, while the Feature Extractor field shows the only currently possible choice.&lt;br /&gt;
&lt;br /&gt;
You can view/edit analysis details by clicking on &amp;quot;Set Analysis Details&amp;quot; and &amp;quot;Set F.E. parameters&amp;quot;&lt;br /&gt;
&lt;br /&gt;
This second form reports all the settings for the parametric (autoregressive) spectral estimation stage. Most of the values are set after the corresponding values used on-line (see BCI2000 setup for Mu). Using the settings in the figure, the analysis software will:&lt;br /&gt;
&lt;br /&gt;
:* analyze data recorded at 200 Hz sampling rate &lt;br /&gt;
:* remove the mean value &lt;br /&gt;
:* sample the spectrum at points starting from 0 Hz to 60 Hz, every 0.2 Hz. &lt;br /&gt;
:* Identify an auroregressive model of order 16 &lt;br /&gt;
:* average these values into 2 Hz wide bins &lt;br /&gt;
:* take a 1 s long epoch of data &lt;br /&gt;
&lt;br /&gt;
You can modify these settings according to your aims. Changing the model order, for instance, brings sometimes to interesting results. Remember though that in the online version, spectral estimation is performed in epochs as short as 200 ms (i.e. 40 samples, at 200 Hz sampling rate), so you should avoid using a model order higher than half the samples available in the epoch.&lt;br /&gt;
When you are finished, remember to confirm your choices by slecting DONE. &lt;br /&gt;
&lt;br /&gt;
In addition, a button in the Spectral Extimation frame allows you to revert to the original values. &lt;br /&gt;
&lt;br /&gt;
Altogether you have to specify:&lt;br /&gt;
&lt;br /&gt;
:* which data (in each trial) you want to take into account. Mu will only use the part of the trial when the cursor is visible, while MuExtended will take into account all the period when the target is visible. To learn more, see section D2Box Application States &lt;br /&gt;
:* If you have made an artifact rejection (or noted on the run sheet during the acquisition which trials contain artifacts), you can instruct the software not to use them&lt;br /&gt;
:* Finally, you must decide how the software must extract EEG epochs from the continuous data&lt;br /&gt;
The epochs can be partially overlapped. This attenuates the data loss in case the length of a trial is not a multiple of the length of an epoch.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The percentage of overlap can be set both in Mario GUI and in any batch script. It is equal to the value of the &#039;&#039;MU_params.overlapping&#039;&#039; variable and the corresponding GUI field can be found by clickiing on &#039;&#039;Set Analysis Details&#039;&#039; on MARIO main form.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
At this point you can start the analysis by clicking on the Evaluate and Plot button.&lt;br /&gt;
&lt;br /&gt;
[[Image:Mu Rhy8.jpg]]&lt;br /&gt;
&lt;br /&gt;
== View Results ==&lt;br /&gt;
&lt;br /&gt;
The first figure that appears is the R-square matrix (channels x frequency bins)&lt;br /&gt;
=== R-square Matrix ===&lt;br /&gt;
&lt;br /&gt;
The r-square matrix highlights the most relevant spectral features for the separation of the two classes of EEG - Cursor Up (target 1) and Cursor Down (target 2).&lt;br /&gt;
&lt;br /&gt;
[[Image:Mu Rhy8.jpg]]&lt;br /&gt;
&lt;br /&gt;
Each row of the matrix is related to a single channel, while a column represents a frequency bin (labeled with its central frequency). The color codes the statistical significance of the difference between the two kinds of evoked potentials.&lt;br /&gt;
&lt;br /&gt;
Thus a red color would mean that, on that channel and for that frequency, the &amp;quot;Up&amp;quot; EEG is significantly synchronized with respect to &amp;quot;Down&amp;quot; EEG.&lt;br /&gt;
&lt;br /&gt;
Clicking on a cell of the matrix will open two more windows:&lt;br /&gt;
&lt;br /&gt;
* Power spectral distribution of the selected channel&lt;br /&gt;
* Topographic maps at the selected frequency.&lt;br /&gt;
&lt;br /&gt;
You can choose whether to overwrite or to put the most recently evoked figures beside the previous one. Two sets of waveform/topography figures are available, and are linked to the click of the left, the central or right mouse button.&lt;br /&gt;
&amp;lt;b&amp;gt;Left Button&amp;lt;/b&amp;gt; will create/overwrite a first figure, &amp;lt;b&amp;gt;Right Button&amp;lt;/b&amp;gt; will do the same on a second figure, the &amp;lt;b&amp;gt;Central Button&amp;lt;/b&amp;gt; will always open a new plot.&lt;br /&gt;
&lt;br /&gt;
=== Power Spectra and Topographic Plots ===&lt;br /&gt;
&lt;br /&gt;
In the lower panel you can find the spectral density of power for both classes of EEG. The Blue line refers to the &amp;quot;Up&amp;quot; condition, while the Red line refers to the &amp;quot;Down&amp;quot; condition.&lt;br /&gt;
We can see that at the vertex the &amp;quot;Down&amp;quot; condition is generally more synchronized than the &amp;quot;Up&amp;quot;, with maximal difference in the beta band, consistently with what is shown by the R-square matrix.  The proportinality between spectral differences and R-square is anyway rough, since r-square is sensitive to the dispersion (variance) of single trials; thus, small differences between spectra could bring to a high r-square, if they were very reproducible.&lt;br /&gt;
&lt;br /&gt;
The peak around 50 Hz is due to mains disturbance; this also allows you to appreciate the leakage introduced by the spectral estimation.&lt;br /&gt;
&lt;br /&gt;
[[Image:Mu_Rhy9.jpg]]&lt;br /&gt;
&lt;br /&gt;
Over the spectral graph, a topographic plot shows the scalp distribution of the r-square.&lt;br /&gt;
&lt;br /&gt;
The color coding is the same as the r-square matrix figure, and values on each channel are interpolated to create a continuous bidimensional map. The higher the number of electrodes, the more accurate is the map. With Surface Laplacian spatial filtering, the number of channels shown on the scalp may not coincide with the whole number of electrodes, since the value of the laplacian is not computed on the border channels.&lt;br /&gt;
&lt;br /&gt;
===Interpretation of the Results===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The first step in the preliminary analysis of P300 BCI data is to find the absolute maximum of r-square. This simple statement must be mediated with a proper knowledge of physiological phenomena. In fact, we do not expect any sensorimotor activity at 3 Hz, so if the absolute maximum is at that frequency, you must suspect that it is actually an artifact. The same holds true if the spatial localization of the peak is far away from the centro-parietal electrodes.&lt;br /&gt;
&lt;br /&gt;
From a practical point of view, it is not important, now, to understand the reasons that different components explain the desynchronization peak on Cz at 17 Hz, so long as we are confident that this component is stable enough to be exploitable during the next session to control the cursor.&lt;br /&gt;
&lt;br /&gt;
The absolute value of R-square is mathematically bound to lie in the interval between 0 and 1. Values above 0.4 allow a rate of missed target on the order of a few percent. Values around 0.1 are promising. Values below 0.03 are possibly due to random fluctuations. All the previous figures refer to analyses made on 240 trials.&lt;br /&gt;
&#039;&#039;&amp;lt;b&amp;gt;Beware of artifacts!&amp;lt;/b&amp;gt;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
During the acquisition, you should be particularly careful to avoid artifacts. While EOG and blink artifacts are confined to very low frequencies, EMG artifacts are mostly on the beta band and could largely overlap with the frequency band that characterizes the mu rhythm.&lt;br /&gt;
&lt;br /&gt;
If contaminated data was acquired, then you have two problems:&lt;br /&gt;
&lt;br /&gt;
:* Realize that EMG is superimposed on the to data&lt;br /&gt;
:* Distinguish between spectral modulation introduced by EEG and by EMG &lt;br /&gt;
&lt;br /&gt;
The first task is not as trivial as it might appear. If you did not acquire the data yourself (or even if you did) you might complete the analysis procedure without giving a single glance to the raw data. So you must be particularly careful when you analyze the R-square maps, and always check if the peak you are seeing might be due to an artifact.&lt;br /&gt;
&lt;br /&gt;
Discriminant features between EEG and EMG are both in the frequency distribution and in the spatial distribution.&lt;br /&gt;
&lt;br /&gt;
EMG that strongly affects the recordings is mostly generated by muscles at the forehead or close to the ears/jaws. Thus, their spatial distribution is such that the most responsive channel is one of those at the border of the montage. Of course, due to volume conduction, the effects can be seen even on electrodes on the opposite part of the montage, but they show a degrading pattern.&lt;br /&gt;
On the other hand, a peak that shows its maximum on a central channel, can hardly be generated by a muscle or by other non-cephalic source.&lt;br /&gt;
&lt;br /&gt;
The spectrum of EEG is mainly concentrated in the alpha band, with a possible flatter and lower peak in beta. With the exception of the beta peak/plateau, the EEG spectrum decreases almost linearly (if measured in dB) after 12 Hz.&lt;br /&gt;
On the other hand, the EMG spectrum becomes significant at about 20 Hz and is still very high at the highest frequencies we usually analyze (60 Hz). A spectrum with a pattern more similar to the latter, may indicate that non-EEG activity is present in the data.&lt;br /&gt;
&lt;br /&gt;
==Improving the Analysis==&lt;br /&gt;
&lt;br /&gt;
The first cause of an unsuccessful analysis is poor quality of the recording. For this reason it is highly recommended that, at least for the first experiments, the subject be highly motivated and cooperative. If this is the case, data of low quality are usually present in one or a few runs. And if the experimenter is careful enough, he/she should have noted the occurrence of strong artifacts on the run sheet.&lt;br /&gt;
In this case, the next step is to repeat an unsatisfactory data analysis after having excluded the (putative) bad runs.&lt;br /&gt;
To do this, just go back to the file selection dialog, choose LOAD Data again and load only the runs that you believe are clean. The number of runs should not be too low (as a rule of thumb, the data set should contain at least 100 trials), otherwise the r-square statistical analysis would loose sensitivity.&lt;br /&gt;
&lt;br /&gt;
== Analyzing the Screening ==&lt;br /&gt;
&lt;br /&gt;
The screening experiment is not different from a regular training session, from the point of view of data format. You will have four sets (horizontal movement, horizontal imagination, vertical movement, and vertical imagination) of three runs, containing EEG acquired in two conditions (up and down, or left and right).&lt;br /&gt;
&lt;br /&gt;
Start analyzing the vertical movement execution, and mark a few possible responsive features. The analysis on the vertical movement imagination should confirm (though with a lower R-square) those that are actually related to sensorimotor cognitive states.&lt;br /&gt;
&lt;br /&gt;
In the case that no reliable responsive EEG feature is found, the analysis can be repeated on the horizontal dataset.&lt;br /&gt;
&lt;br /&gt;
If both the vertical and horizontal dataset show responsive features, and these are different, the subject should be trained for several sessions on vertical training until he/she decreases the error rate below 10%. At that point, the training of the horizontal modulation can begin, with the aim that, the subject will eventually control both the vertical and the horizontal simultaneously in a two-dimensional task.&lt;br /&gt;
&lt;br /&gt;
==Conclusions==&lt;br /&gt;
&lt;br /&gt;
If you are confident that you have found a significant difference between conditions that is due to EEG rather than an artifact, and that reflects a cognitive process that is likely to be reproduced (or even enhanced with training) in the next session, you have reached your goal.&lt;br /&gt;
The next time the same subject practices with the D2Box Application, you will have to change the MUD matrix so that it reflects the feature that you just outlined.&lt;br /&gt;
&lt;br /&gt;
==Troubleshooting==&lt;br /&gt;
&lt;br /&gt;
Some OpenGL drivers may sometimes show defective figures like the following:&lt;br /&gt;
&lt;br /&gt;
[[Image:Defective.jpg]]&lt;br /&gt;
&lt;br /&gt;
Matlab customers can get around this problem using this simple procedure:&lt;br /&gt;
:* Select the defective figure window&lt;br /&gt;
:* Go to the Matlab Command Window&lt;br /&gt;
:* Execute one of the following command line:&lt;br /&gt;
:**set(gcf, &#039;Renderer&#039;, &#039;Painters&#039;) &lt;br /&gt;
:**set(gcf, &#039;Renderer&#039;, &#039;zbuffer&#039;)&lt;br /&gt;
&lt;br /&gt;
The figure will be a plot using a different renderer (Painters or zBuffer).&lt;/div&gt;</summary>
		<author><name>Atennissen</name></author>
	</entry>
	<entry>
		<id>https://www.bci2000.org/mediawiki/index.php?title=Mu_Rhythm_Off-line_Analysis_Tutorial&amp;diff=1784</id>
		<title>Mu Rhythm Off-line Analysis Tutorial</title>
		<link rel="alternate" type="text/html" href="https://www.bci2000.org/mediawiki/index.php?title=Mu_Rhythm_Off-line_Analysis_Tutorial&amp;diff=1784"/>
		<updated>2007-05-10T19:45:38Z</updated>

		<summary type="html">&lt;p&gt;Atennissen: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Starting an Analysis Session ==&lt;br /&gt;
&lt;br /&gt;
Every recording session has its own history. It is very difficult to say in advance what might happen during the recording. So we will assume that everything was perfect (the subject collaborated, no channel went lost, etc); later on we will consider the main causes of contamination, how to recognize it and what to do.&lt;br /&gt;
&lt;br /&gt;
If the recording session runs smoothly, you should now have in the folder &#039;&#039;\TestData\Data\Mu&#039;&#039;,   two files named &#039;&#039;ALFAS006R01.dat&#039;&#039; and &#039;&#039;ALFAS006R02.dat&#039;&#039;, corresponding to two of the eight runs usually recorded, respectively.&lt;br /&gt;
&lt;br /&gt;
Before you start the analysis you should locate the correct montage file on your hard disk. This is a file that describes the list of channels that were acquired. In this tutorial we will use &#039;&#039;Complete_Montage(suggested choice).mmf&#039;&#039;, which is located in the folder &#039;&#039;\TestData\Montage&#039;&#039;. If you need to edit the *.mmf file, check its data format.&lt;br /&gt;
&lt;br /&gt;
== Opening Files with Mario ==&lt;br /&gt;
&lt;br /&gt;
After having run mario.exe, press &amp;quot;Select Data Files&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
[[Image:Mu Rhy5.jpg]]&lt;br /&gt;
&lt;br /&gt;
A dialog window will ask you to select the dat files. You can either select a single data file, or select multiple files. This time, we will select all files in the dataset.&lt;br /&gt;
&lt;br /&gt;
A green box will surround the Raw Data box in the main window.&lt;br /&gt;
&lt;br /&gt;
As an optional (but recommended) operation, click on the LOAD MONTAGE button and choose the mmf file. This will allow you to see the labels of each channel and allow you to apply spatial filters that depend on the electrode position.&lt;br /&gt;
&lt;br /&gt;
You can load an additional parameters file with choices different from those used during the experiment.&lt;br /&gt;
&lt;br /&gt;
At this point, you can check that Mu is selected in the Analysis menu (indicating that a Mu dataset has been recognized) and click on the LOAD DATA button to confirm your choices. This will enable the EDIT CHANNEL LIST button that you can use to select the channels you want to include in your analysis.&lt;br /&gt;
&lt;br /&gt;
== Selecting Channels ==&lt;br /&gt;
&lt;br /&gt;
When you select the EDIT CHANNEL LIST button, two forms will show you the channel list (valid ones and not-valid ones) and an image showing valid channels and their location.&lt;br /&gt;
&lt;br /&gt;
Clicking on Add and Remove buttons allows you to move a channel from one list to the other, enabling or disabling it.&lt;br /&gt;
&lt;br /&gt;
== Selecting the Spatial Filter ==&lt;br /&gt;
&lt;br /&gt;
Return to the main window, and you can choose which filter to apply for your analysis, selecting from the following filter choices:&lt;br /&gt;
&lt;br /&gt;
:*RAW&lt;br /&gt;
:*CAR&lt;br /&gt;
:*Large Laplacian&lt;br /&gt;
:*Small Laplacian&lt;br /&gt;
&lt;br /&gt;
Common Average Reference (CAR) will be fine for most of the situations.&lt;br /&gt;
&lt;br /&gt;
We hope, soon, to release a user defined solution for any custom analysis.&lt;br /&gt;
&lt;br /&gt;
== Feature Extraction Analysis ==&lt;br /&gt;
&lt;br /&gt;
The Analysis field in the Feature Extraction panel will appear automatically according to the files loaded, while the Feature Extractor field shows the only currently possible choice.&lt;br /&gt;
&lt;br /&gt;
You can view/edit analysis details by clicking on &amp;quot;Set Analysis Details&amp;quot; and &amp;quot;Set F.E. parameters&amp;quot;&lt;br /&gt;
&lt;br /&gt;
This second form reports all the settings for the parametric (autoregressive) spectral estimation stage. Most of the values are set after the corresponding values used on-line (see BCI2000 setup for Mu). Using the settings in the figure, the analysis software will:&lt;br /&gt;
&lt;br /&gt;
:* analyze data recorded at 200 Hz sampling rate &lt;br /&gt;
:* remove the mean value &lt;br /&gt;
:* sample the spectrum at points starting from 0 Hz to 60 Hz, every 0.2 Hz. &lt;br /&gt;
:* Identify an auroregressive model of order 16 &lt;br /&gt;
:* average these values into 2 Hz wide bins &lt;br /&gt;
:* take a 1 s long epoch of data &lt;br /&gt;
&lt;br /&gt;
You can modify these settings according to your aims. Changing the model order, for instance, brings sometimes to interesting results. Remember though that in the online version, spectral estimation is performed in epochs as short as 200 ms (i.e. 40 samples, at 200 Hz sampling rate), so you should avoid using a model order higher than half the samples available in the epoch.&lt;br /&gt;
When you are finished, remember to confirm your choices by slecting DONE. &lt;br /&gt;
&lt;br /&gt;
In addition, a button in the Spectral Extimation frame allows you to revert to the original values. &lt;br /&gt;
&lt;br /&gt;
Altogether you have to specify:&lt;br /&gt;
&lt;br /&gt;
:* which data (in each trial) you want to take into account. Mu will only use the part of the trial when the cursor is visible, while MuExtended will take into account all the period when the target is visible. To learn more, see section D2Box Application States &lt;br /&gt;
:* If you have made an artifact rejection (or noted on the run sheet during the acquisition which trials contain artifacts), you can instruct the software not to use them&lt;br /&gt;
:* Finally, you must decide how the software must extract EEG epochs from the continuous data&lt;br /&gt;
The epochs can be partially overlapped. This attenuates the data loss in case the length of a trial is not a multiple of the length of an epoch.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The percentage of overlap can be set both in Mario GUI and in any batch script. It is equal to the value of the &#039;&#039;MU_params.overlapping&#039;&#039; variable and the corresponding GUI field can be found by clickiing on &#039;&#039;Set Analysis Details&#039;&#039; on MARIO main form.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
At this point you can start the analysis by clicking on the Evaluate and Plot button.&lt;br /&gt;
&lt;br /&gt;
[[Image:Mu Rhy8.jpg]]&lt;br /&gt;
&lt;br /&gt;
== View Results ==&lt;br /&gt;
&lt;br /&gt;
The first figure that appears is the R-square matrix (channels x frequency bins)&lt;br /&gt;
=== R-square Matrix ===&lt;br /&gt;
&lt;br /&gt;
The r-square matrix highlights the most relevant spectral features for the separation of the two classes of EEG - Cursor Up (target 1) and Cursor Down (target 2).&lt;br /&gt;
&lt;br /&gt;
[[Image:Mu Rhy8.jpg]]&lt;br /&gt;
&lt;br /&gt;
Each row of the matrix is related to a single channel, while a column represents a frequency bin (labeled with its central frequency). The color codes the statistical significance of the difference between the two kinds of evoked potentials.&lt;br /&gt;
&lt;br /&gt;
Thus a red color would mean that, on that channel and for that frequency, the &amp;quot;Up&amp;quot; EEG is significantly synchronized with respect to &amp;quot;Down&amp;quot; EEG.&lt;br /&gt;
&lt;br /&gt;
Clicking on a cell of the matrix will open two more windows:&lt;br /&gt;
&lt;br /&gt;
* Power spectral distribution of the selected channel&lt;br /&gt;
* Topographic maps at the selected frequency.&lt;br /&gt;
&lt;br /&gt;
You can choose whether to overwrite or to put the most recently evoked figures beside the previous one. Two sets of waveform/topography figures are available, and are linked to the click of the left, the central or right mouse button.&lt;br /&gt;
&amp;lt;b&amp;gt;Left Button&amp;lt;/b&amp;gt; will create/overwrite a first figure, &amp;lt;b&amp;gt;Right Button&amp;lt;/b&amp;gt; will do the same on a second figure, the &amp;lt;b&amp;gt;Central Button&amp;lt;/b&amp;gt; will always open a new plot.&lt;br /&gt;
&lt;br /&gt;
=== Power Spectra and Topographic Plots ===&lt;br /&gt;
&lt;br /&gt;
In the lower panel you can find the spectral density of power for both classes of EEG. The Blue line refers to the &amp;quot;Up&amp;quot; condition, while the Red line refers to the &amp;quot;Down&amp;quot; condition.&lt;br /&gt;
We can see that at the vertex the &amp;quot;Down&amp;quot; condition is generally more synchronized than the &amp;quot;Up&amp;quot;, with maximal difference in the beta band, consistently with what is shown by the R-square matrix.  The proportinality between spectral differences and R-square is anyway rough, since r-square is sensitive to the dispersion (variance) of single trials; thus, small differences between spectra could bring to a high r-square, if they were very reproducible.&lt;br /&gt;
&lt;br /&gt;
The peak around 50 Hz is due to mains disturbance; this also allows you to appreciate the leakage introduced by the spectral estimation.&lt;br /&gt;
&lt;br /&gt;
[[Image:Mu_Rhy9.jpg]]&lt;br /&gt;
&lt;br /&gt;
Over the spectral graph, a topographic plot shows the scalp distribution of the r-square.&lt;br /&gt;
&lt;br /&gt;
The color coding is the same as the r-square matrix figure, and values on each channel are interpolated to create a continuous bidimensional map. The higher the number of electrodes, the more accurate is the map. With Surface Laplacian spatial filtering, the number of channels shown on the scalp may not coincide with the whole number of electrodes, since the value of the laplacian is not computed on the border channels.&lt;br /&gt;
&lt;br /&gt;
==Interpretation of the Results==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The first step in the preliminary analysis of P300 BCI data is to find the absolute maximum of r-square. This simple statement must be mediated with a proper knowledge of physiological phenomena. In fact, we do not expect any sensorimotor activity at 3 Hz, so if the absolute maximum is at that frequency, you must suspect that it is actually an artifact. The same holds true if the spatial localization of the peak is far away from the centro-parietal electrodes.&lt;br /&gt;
&lt;br /&gt;
From a practical point of view, it is not important, now, to understand the reasons that different components explain the desynchronization peak on Cz at 17 Hz, so long as we are confident that this component is stable enough to be exploitable during the next session to control the cursor.&lt;br /&gt;
&lt;br /&gt;
The absolute value of R-square is mathematically bound to lie in the interval between 0 and 1. Values above 0.4 allow a rate of missed target on the order of a few percent. Values around 0.1 are promising. Values below 0.03 are possibly due to random fluctuations. All the previous figures refer to analyses made on 240 trials.&lt;br /&gt;
&#039;&#039;&amp;lt;b&amp;gt;Beware of artifacts!&amp;lt;/b&amp;gt;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
During the acquisition, you should be particularly careful to avoid artifacts. While EOG and blink artifacts are confined to very low frequencies, EMG artifacts are mostly on the beta band and could largely overlap with the frequency band that characterizes the mu rhythm.&lt;br /&gt;
&lt;br /&gt;
If contaminated data was acquired, then you have two problems:&lt;br /&gt;
&lt;br /&gt;
:* Realize that EMG is superimposed on the to data&lt;br /&gt;
:* Distinguish between spectral modulation introduced by EEG and by EMG &lt;br /&gt;
&lt;br /&gt;
The first task is not as trivial as it might appear. If you did not acquire the data yourself (or even if you did) you might complete the analysis procedure without giving a single glance to the raw data. So you must be particularly careful when you analyze the R-square maps, and always check if the peak you are seeing might be due to an artifact.&lt;br /&gt;
&lt;br /&gt;
Discriminant features between EEG and EMG are both in the frequency distribution and in the spatial distribution.&lt;br /&gt;
&lt;br /&gt;
EMG that strongly affects the recordings is mostly generated by muscles at the forehead or close to the ears/jaws. Thus, their spatial distribution is such that the most responsive channel is one of those at the border of the montage. Of course, due to volume conduction, the effects can be seen even on electrodes on the opposite part of the montage, but they show a degrading pattern.&lt;br /&gt;
On the other hand, a peak that shows its maximum on a central channel, can hardly be generated by a muscle or by other non-cephalic source.&lt;br /&gt;
&lt;br /&gt;
The spectrum of EEG is mainly concentrated in the alpha band, with a possible flatter and lower peak in beta. With the exception of the beta peak/plateau, the EEG spectrum decreases almost linearly (if measured in dB) after 12 Hz.&lt;br /&gt;
On the other hand, the EMG spectrum becomes significant at about 20 Hz and is still very high at the highest frequencies we usually analyze (60 Hz). A spectrum with a pattern more similar to the latter, may indicate that non-EEG activity is present in the data.&lt;br /&gt;
&lt;br /&gt;
==Improving the Analysis==&lt;br /&gt;
&lt;br /&gt;
The first cause of an unsuccessful analysis is poor quality of the recording. For this reason it is highly recommended that, at least for the first experiments, the subject be highly motivated and cooperative. If this is the case, data of low quality are usually present in one or a few runs. And if the experimenter is careful enough, he/she should have noted the occurrence of strong artifacts on the run sheet.&lt;br /&gt;
In this case, the next step is to repeat an unsatisfactory data analysis after having excluded the (putative) bad runs.&lt;br /&gt;
To do this, just go back to the file selection dialog, choose LOAD Data again and load only the runs that you believe are clean. The number of runs should not be too low (as a rule of thumb, the data set should contain at least 100 trials), otherwise the r-square statistical analysis would loose sensitivity.&lt;br /&gt;
&lt;br /&gt;
== Analyzing the Screening ==&lt;br /&gt;
&lt;br /&gt;
The screening experiment is not different from a regular training session, from the point of view of data format. You will have four sets (horizontal movement, horizontal imagination, vertical movement, and vertical imagination) of three runs, containing EEG acquired in two conditions (up and down, or left and right).&lt;br /&gt;
&lt;br /&gt;
Start analyzing the vertical movement execution, and mark a few possible responsive features. The analysis on the vertical movement imagination should confirm (though with a lower R-square) those that are actually related to sensorimotor cognitive states.&lt;br /&gt;
&lt;br /&gt;
In the case that no reliable responsive EEG feature is found, the analysis can be repeated on the horizontal dataset.&lt;br /&gt;
&lt;br /&gt;
If both the vertical and horizontal dataset show responsive features, and these are different, the subject should be trained for several sessions on vertical training until he/she decreases the error rate below 10%. At that point, the training of the horizontal modulation can begin, with the aim that, the subject will eventually control both the vertical and the horizontal simultaneously in a two-dimensional task.&lt;br /&gt;
&lt;br /&gt;
==Conclusions==&lt;br /&gt;
&lt;br /&gt;
If you are confident that you have found a significant difference between conditions that is due to EEG rather than an artifact, and that reflects a cognitive process that is likely to be reproduced (or even enhanced with training) in the next session, you have reached your goal.&lt;br /&gt;
The next time the same subject practices with the D2Box Application, you will have to change the MUD matrix so that it reflects the feature that you just outlined.&lt;br /&gt;
&lt;br /&gt;
==Troubleshooting==&lt;br /&gt;
&lt;br /&gt;
Some OpenGL drivers may sometimes show defective figures like the following:&lt;br /&gt;
&lt;br /&gt;
[[Image:Defective.jpg]]&lt;br /&gt;
&lt;br /&gt;
Matlab customers can get around this problem using this simple procedure:&lt;br /&gt;
:* Select the defective figure window&lt;br /&gt;
:* Go to the Matlab Command Window&lt;br /&gt;
:* Execute one of the following command line:&lt;br /&gt;
:**set(gcf, &#039;Renderer&#039;, &#039;Painters&#039;) &lt;br /&gt;
:**set(gcf, &#039;Renderer&#039;, &#039;zbuffer&#039;)&lt;br /&gt;
&lt;br /&gt;
The figure will be a plot using a different renderer (Painters or zBuffer).&lt;/div&gt;</summary>
		<author><name>Atennissen</name></author>
	</entry>
	<entry>
		<id>https://www.bci2000.org/mediawiki/index.php?title=Programming_Howto:SVN_Client_Setup&amp;diff=1783</id>
		<title>Programming Howto:SVN Client Setup</title>
		<link rel="alternate" type="text/html" href="https://www.bci2000.org/mediawiki/index.php?title=Programming_Howto:SVN_Client_Setup&amp;diff=1783"/>
		<updated>2007-05-10T19:26:10Z</updated>

		<summary type="html">&lt;p&gt;Atennissen: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Setting up TortoiseSVN to access the BCI2000 code repository ==&lt;br /&gt;
To set up TortoiseSVN and download the BCI2000 source code to your computer, follow these steps:&lt;br /&gt;
* Download the latest stable version from http://tortoisesvn.net/, and execute the installer program. This page has been written for version 1.40, but should be pretty independent of TortoiseSVN&#039;s version number.&lt;br /&gt;
* Create or pick an empty folder located on your machine’s harddrive. This will hold your working copy of the BCI2000 source tree, in an automatically created subfolder called &amp;quot;BCI2000.&amp;quot;&lt;br /&gt;
* Right-click the folder you picked in the last step. From the context menu, choose the &amp;quot;SVN Checkout...&amp;quot; option – a dialog window appears.&lt;br /&gt;
* In the dialog window, enter the repository URL: &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;http://www.bci2000.org/svn/trunk&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;, choose &amp;quot;HEAD revision&amp;quot;, and click OK.&lt;br /&gt;
* You will be prompted for your user name and password. This account is the same that you use to log into [http://{{SERVERNAME}}/tracproj Trac] and [[special:userlogin|into this Wiki]].&lt;br /&gt;
&lt;br /&gt;
== Checking out older versions ==&lt;br /&gt;
If you think that the current version of BCI2000 is not working properly, or would like to work with an older version for some other reason, you may enter a &amp;quot;Revision number&amp;quot; into the checkout dialog.&lt;br /&gt;
The &amp;quot;Show Log&amp;quot; button will provide you with an overview of the latest changes and their associated revision numbers.&lt;br /&gt;
&lt;br /&gt;
== Working on Branches ==&lt;br /&gt;
Branches are versions of the source code that are developed in parallel to the main code version, e.g. to incorporate new features without affecting the stable version that is intended for end users.&lt;br /&gt;
To checkout a branch called &amp;quot;myBranch&amp;quot;, the repository URL would be:&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;http://www.bci2000.org/svn/branches/myBranch&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;.&lt;br /&gt;
Otherwise, the checkout process remains the same.&lt;br /&gt;
&lt;br /&gt;
==Troubleshooting==&lt;br /&gt;
* When trying to checkout, update, or commit, you get an error message: &amp;quot;PROPFIND request failed&amp;quot;, &amp;quot;OPTIONS request failed&amp;quot;, &amp;quot;could not connect to server&amp;quot;, or the like.&lt;br /&gt;
:Quite likely, you are behind a firewall, and internet access is over a proxy server.&lt;br /&gt;
:To configure TortoiseSVN for use with a proxy server, right-click your desktop,  choose TortoiseSVN-&amp;gt;Settings-&amp;gt;Network, check &amp;quot;Enable Proxy&amp;quot; and enter the appropriate information. If unsure, contact your local system administrator.&lt;br /&gt;
* You configured TortoiseSVN for use with a proxy server as described above. Now, checking out works fine, however on updates or commits, you get strange errors about failed requests.&lt;br /&gt;
:Your proxy server is not forwarding SVN&#039;s WebDAV requests correctly.&lt;br /&gt;
:To keep the proxy from interfering with the protocol, change your setup to use an encrypted connection:&lt;br /&gt;
:*Right-click on your source tree&#039;s top folder, choose TortoiseSVN-&amp;gt;Relocate.&lt;br /&gt;
:*In the &amp;quot;to URL&amp;quot; edit field, modify &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;http://&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; to read &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;https://&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;.&lt;br /&gt;
:*On the first connection, TortoiseSVN will display a warning message: [[Image:TortoiseCertificateWarning.PNG]]&lt;br /&gt;
::Click &amp;quot;Accept permanently&amp;quot; to continue.&lt;br /&gt;
&lt;br /&gt;
==See also==&lt;br /&gt;
*[[Using TortoiseSVN]]&lt;br /&gt;
&lt;br /&gt;
[[Category:Howto]] [[Category:Development]] [[Category:Preliminaries]]&lt;/div&gt;</summary>
		<author><name>Atennissen</name></author>
	</entry>
	<entry>
		<id>https://www.bci2000.org/mediawiki/index.php?title=Programming_Howto:SVN_Client_Setup&amp;diff=1782</id>
		<title>Programming Howto:SVN Client Setup</title>
		<link rel="alternate" type="text/html" href="https://www.bci2000.org/mediawiki/index.php?title=Programming_Howto:SVN_Client_Setup&amp;diff=1782"/>
		<updated>2007-05-10T19:24:30Z</updated>

		<summary type="html">&lt;p&gt;Atennissen: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Setting up TortoiseSVN to access the BCI2000 code repository ==&lt;br /&gt;
To set up TortoiseSVN and download the BCI2000 source code to your computer, follow these steps:&lt;br /&gt;
* Download the latest stable version from http://tortoisesvn.net/, and execute the installer program. This page has been written for version 1.40, but should be pretty independent of TortoiseSVN&#039;s version number.&lt;br /&gt;
* Create or pick an empty folder located on your machine’s harddrive. This will hold your working copy of the BCI2000 source tree, in an automatically created subfolder called &amp;quot;BCI2000.&amp;quot;&lt;br /&gt;
* Right-click the folder you picked in the last step. From the context menu, choose the &amp;quot;SVN Checkout...&amp;quot; option – a dialog window appears.&lt;br /&gt;
* In the dialog window, enter the repository URL: &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;http://www.bci2000.org/svn/trunk&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;, choose &amp;quot;HEAD revision&amp;quot;, and click OK.&lt;br /&gt;
* You will be prompted for your user name and password. This account is the same that you use to log into [http://{{SERVERNAME}}/tracproj Trac] and [[special:userlogin|into this Wiki]].&lt;br /&gt;
&lt;br /&gt;
== Checking out older versions ==&lt;br /&gt;
If you think that the current version of BCI2000 is not working properly, or would like to work with an older version for some other reason, you may enter a &amp;quot;Revision number&amp;quot; into the checkout dialog.&lt;br /&gt;
The &amp;quot;Show Log&amp;quot; button will provide you with an overview of the latest changes and their associated revision numbers.&lt;br /&gt;
&lt;br /&gt;
== Working on Branches ==&lt;br /&gt;
Branches are versions of the source code that are developed in parallel to the main code version, e.g. to incorporate new features without affecting the stable version that is intended for end users.&lt;br /&gt;
To check out a branch called &amp;quot;myBranch&amp;quot;, the repository URL would be:&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;http://www.bci2000.org/svn/branches/myBranch&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;.&lt;br /&gt;
Otherwise, the checkout process remains the same.&lt;br /&gt;
&lt;br /&gt;
==Troubleshooting==&lt;br /&gt;
* When trying to checkout, update, or commit, you get an error message: &amp;quot;PROPFIND request failed&amp;quot;, &amp;quot;OPTIONS request failed&amp;quot;, &amp;quot;could not connect to server&amp;quot;, or the like.&lt;br /&gt;
:Quite likely, you are behind a firewall, and internet access is over a proxy server.&lt;br /&gt;
:To configure TortoiseSVN for use with a proxy server, right-click your desktop,  choose TortoiseSVN-&amp;gt;Settings-&amp;gt;Network, check &amp;quot;Enable Proxy&amp;quot; and enter the appropriate information. If unsure, contact your local system administrator.&lt;br /&gt;
* You configured TortoiseSVN for use with a proxy server as described above. Now, checking out works fine, however on updates or commits, you get strange errors about failed requests.&lt;br /&gt;
:Your proxy server is not forwarding SVN&#039;s WebDAV requests correctly.&lt;br /&gt;
:To keep the proxy from interfering with the protocol, change your setup to use an encrypted connection:&lt;br /&gt;
:*Right-click on your source tree&#039;s top folder, choose TortoiseSVN-&amp;gt;Relocate.&lt;br /&gt;
:*In the &amp;quot;to URL&amp;quot; edit field, modify &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;http://&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; to read &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;https://&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;.&lt;br /&gt;
:*On the first connection, TortoiseSVN will display a warning message: [[Image:TortoiseCertificateWarning.PNG]]&lt;br /&gt;
::Click &amp;quot;Accept permanently&amp;quot; to continue.&lt;br /&gt;
&lt;br /&gt;
==See also==&lt;br /&gt;
*[[Using TortoiseSVN]]&lt;br /&gt;
&lt;br /&gt;
[[Category:Howto]] [[Category:Development]] [[Category:Preliminaries]]&lt;/div&gt;</summary>
		<author><name>Atennissen</name></author>
	</entry>
	<entry>
		<id>https://www.bci2000.org/mediawiki/index.php?title=Programming_Reference:Filter_Chain&amp;diff=1781</id>
		<title>Programming Reference:Filter Chain</title>
		<link rel="alternate" type="text/html" href="https://www.bci2000.org/mediawiki/index.php?title=Programming_Reference:Filter_Chain&amp;diff=1781"/>
		<updated>2007-05-09T19:21:26Z</updated>

		<summary type="html">&lt;p&gt;Atennissen: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==The Filter Chain==&lt;br /&gt;
As noted in the [[Programming Reference:GenericFilter Class|discussion]] of the &amp;lt;tt&amp;gt;GenericFilter::Process&amp;lt;/tt&amp;gt; function, all &amp;lt;tt&amp;gt;GenericFilter&amp;lt;/tt&amp;gt; descendants inside a BCI2000&lt;br /&gt;
module form a single chain of filters. Each filter&#039;s output forms the input of the&lt;br /&gt;
subsequent filter.&lt;br /&gt;
&lt;br /&gt;
==Filter Instantiation==&lt;br /&gt;
Creating instances of all filter classes inside a module, and building the filter chain, is handled by the framework. However, it needs a hint to determine the sequence in which filters are to be arranged. In general, this hint consists of a single statement placed inside your filter&#039;s .cpp file:&amp;lt;pre&amp;gt;&lt;br /&gt;
RegisterFilter( MyFilter, 2.C );&amp;lt;/pre&amp;gt;&lt;br /&gt;
The first argument to this statement is the class name of your filter;&lt;br /&gt;
the second argument is a string value (given without quotes) that determines the&lt;br /&gt;
relative position of your filter in the filter chain.&lt;br /&gt;
This is done by applying the simple rule that the filter positions in the chain match the alphanumeric sorting order of the associated postion strings of the filters. &lt;br /&gt;
This scheme allows you to place an additional filter between existing ones without changing the position strings of the existing filters.&lt;br /&gt;
&lt;br /&gt;
==Signal Processing Filter Instantiation==&lt;br /&gt;
In principle, the above scheme allows to you add filters to a module&#039;s filter chain&lt;br /&gt;
without&lt;br /&gt;
modification to the existing source code, simply by adding a .cpp file&lt;br /&gt;
with a&lt;br /&gt;
&amp;lt;tt&amp;gt;RegisterFilter&amp;lt;/tt&amp;gt; statement to the project.&lt;br /&gt;
However for Signal Processing modules, it is more desirable to&lt;br /&gt;
have an&lt;br /&gt;
explicit representation of the entire filter chain centralized in one&lt;br /&gt;
place.&lt;br /&gt;
So, for each individual Signal Processing module there is one file&lt;br /&gt;
&amp;lt;tt&amp;gt;PipeDefinition.cpp&amp;lt;/tt&amp;gt; that defines the filter chain as a&lt;br /&gt;
sequence of&lt;br /&gt;
&amp;lt;tt&amp;gt;Filter&amp;lt;/tt&amp;gt; statements (see [[Programming Tutorial:Implementing a Signal Processing Filter]] for&lt;br /&gt;
an&lt;br /&gt;
example).&lt;/div&gt;</summary>
		<author><name>Atennissen</name></author>
	</entry>
	<entry>
		<id>https://www.bci2000.org/mediawiki/index.php?title=Technical_Reference:Parameter_Definition&amp;diff=1780</id>
		<title>Technical Reference:Parameter Definition</title>
		<link rel="alternate" type="text/html" href="https://www.bci2000.org/mediawiki/index.php?title=Technical_Reference:Parameter_Definition&amp;diff=1780"/>
		<updated>2007-05-09T19:18:57Z</updated>

		<summary type="html">&lt;p&gt;Atennissen: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page describes the concept of BCI2000 parameters, in conjunction with their textual representation as a &amp;quot;parameter line&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
For information about how to access parameters from code, please refer to [[Programming Reference:Parameters]].&lt;br /&gt;
For information about individual parameters, please refer to [[User Reference:Parameters]].&lt;br /&gt;
&lt;br /&gt;
==Parameter Concept==&lt;br /&gt;
Parameters are variables that primarily represent user configuration choices. Typical entities encoded by parameters are:&lt;br /&gt;
*size and location of the feedback window &lt;br /&gt;
*subject ID&lt;br /&gt;
*sampling rate&lt;br /&gt;
*spatial filtering matrix.&lt;br /&gt;
&lt;br /&gt;
Typically, parameters are constant throughout a run, often throughout a session or an entire experiment.&lt;br /&gt;
In a [[BCI2000 data file]], a full set of parameters is stored along with the data, allowing for reconstruction of the system configuration off-line.&lt;br /&gt;
&lt;br /&gt;
As parameters represent user choices, the direction of information flow generally is Parameter Value-&amp;gt;BCI2000 Module, i.e. parameter information is used to set BCI2000 modules to a defined state at initialization time.&lt;br /&gt;
There are, however, some important exceptions to that rule.&lt;br /&gt;
*&#039;&#039;Source Modules&#039;&#039; may not be able to control all aspects of data acquisition. Control is limited by the design of the vendor-provided software interface to data acquisition hardware. As a typcial example, consider an EEG amplifier connected through a TCP-based socket interface. Generally, the amplifier will be configured in a separate user interface, and BCI2000 source module parameters such as &amp;lt;tt&amp;gt;SourceCh&amp;lt;/tt&amp;gt; (number of channels) or &amp;lt;tt&amp;gt;SamplingRate&amp;lt;/tt&amp;gt; must be chosen in accordance with that external UI&#039;s settings.&lt;br /&gt;
*&#039;&#039;System-internal Configuration&#039;&#039; is represented as parameters, and of potential interest to the user, but not user configurable. These parameters are placed in the configuration editor&#039;s &#039;&#039;System&#039;&#039; tab. Important examples comprise versioning information (e.g., the &amp;lt;tt&amp;gt;EEGSourceVersion&amp;lt;/tt&amp;gt; parameter), others govern the connection between modules (e.g., the &amp;lt;tt&amp;gt;EEGSourceIP&amp;lt;/tt&amp;gt; parameter).&lt;br /&gt;
*&#039;&#039;Automatic Adaptation&#039;&#039; to the subject&#039;s brain signals may be reflected by automatically updated parameters. For such parameters, the user specifies initial parameter values that may be overwritten at the end of a run. Unless changed by the user, these modified values will be the next run&#039;s initial values, and documented as such in that run&#039;s data file. As typical examples, consider the &#039;&#039;Normalizer&#039;&#039; filter&#039;s  &amp;lt;tt&amp;gt;NormalizerOffsets&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;NormalizerGains&amp;lt;/tt&amp;gt; parameters.&lt;br /&gt;
&lt;br /&gt;
==Parameter Lines==&lt;br /&gt;
Parameter lines are a human-readable format used to represent individual parameters in:&lt;br /&gt;
*[[BCI2000 parameter files]]&lt;br /&gt;
*[[BCI2000 data files]]&lt;br /&gt;
*[[BCI2000 messages]] sent between modules.&lt;br /&gt;
&lt;br /&gt;
The basic format of a parameter line is&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Section DataType Name= Value DefaultValue LowRange HighRange // Comment&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Note that the = sign must follow the &amp;lt;tt&amp;gt;Name&amp;lt;/tt&amp;gt; field immediately, without&lt;br /&gt;
white space. However, white space &#039;&#039;after&#039;&#039; the = sign is mandatory.&lt;br /&gt;
&lt;br /&gt;
If DataType is &#039;&#039;list, intlist&#039;&#039;  or &#039;&#039;floatlist&#039;&#039;, the format is as follows:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Section DataType Name= (NumValues|Labels) Value(s) DefaultValue LowRange HighRange &lt;br /&gt;
  // Comment&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
where &amp;lt;tt&amp;gt;Labels&amp;lt;/tt&amp;gt; is a list of textual labels that optionally&lt;br /&gt;
substitute the number denoted by &amp;lt;tt&amp;gt;NumValues&amp;lt;/tt&amp;gt;. A list of labels&lt;br /&gt;
is enclosed by &amp;lt;nowiki&amp;gt;{} or []&amp;lt;/nowiki&amp;gt;, as in&lt;br /&gt;
&amp;lt;tt&amp;gt;&amp;lt;nowiki&amp;gt;[low medium high]&amp;lt;/nowiki&amp;gt;&amp;lt;/tt&amp;gt;.&lt;br /&gt;
If DataType is &#039;&#039;matrix&#039;&#039; , the format is as follows:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Section DataType Name= (NumRows|RowLabels)&lt;br /&gt;
    (NumColumns|ColumnLabels) Value(s) DefaultValue LowRange&lt;br /&gt;
    HighRange // Comment&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
where, again, each NumValues entry may be substituted by a list of&lt;br /&gt;
textual labels.&lt;br /&gt;
For matrices, values are given in column-major order, i.e. listing&lt;br /&gt;
values from the first column first, then values from the second column,&lt;br /&gt;
and so on, as in&lt;br /&gt;
 Value(0,0) Value(0,1) ... Value(0,m) Value(1,0) Value(1,1) ... Value(1,m) ...&lt;br /&gt;
&lt;br /&gt;
===Data Types===&lt;br /&gt;
The DataType field is not interpreted in a very strict sense. &lt;br /&gt;
Rather, parameter values are always stored as strings, and converted into&lt;br /&gt;
numerical values only when accessed as such from BCI2000 modules.&lt;br /&gt;
For consistency, and to avoid user confusion, the following primitive types&lt;br /&gt;
should be specified as appropriate:&lt;br /&gt;
{|border=&amp;quot;1&amp;quot;&lt;br /&gt;
|+ Primitive Parameter Data Types&lt;br /&gt;
! Name !! Description&lt;br /&gt;
|-&lt;br /&gt;
| variant || unspecified type&lt;br /&gt;
|-&lt;br /&gt;
| int || unlimited range integer value&lt;br /&gt;
|-&lt;br /&gt;
| float || unlimited range, arbitrary precision float value&lt;br /&gt;
|-&lt;br /&gt;
| string || any string of characters (see the &#039;&#039;Special characters&#039;&#039; section for details)&lt;br /&gt;
|}&lt;br /&gt;
A list or matrix type may be formed from these primitive types when concatenated with &#039;&#039;list&#039;&#039; or &#039;&#039;matrix&#039;&#039;, as in &#039;&#039;intlist&#039;&#039;, &#039;&#039;stringmatrix&#039;&#039;.&lt;br /&gt;
For a list or matrix with entries of unspecified type, use an unprefixed &#039;&#039;list&#039;&#039; or &#039;&#039;matrix&#039;&#039; rather than &#039;&#039;variantlist&#039;&#039; or &#039;&#039;variantmatrix&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
===Special Characters===&lt;br /&gt;
To allow for special characters and&lt;br /&gt;
white space&lt;br /&gt;
within parameter values and textual labels, an URL-like encoding&lt;br /&gt;
scheme is adopted.&lt;br /&gt;
In this encoding, a &amp;lt;tt&amp;gt;%&amp;lt;/tt&amp;gt; character followed by up to two &lt;br /&gt;
hexadecimal digits&lt;br /&gt;
represents a byte value in hexadecimal notation which is interpreted&lt;br /&gt;
according to&lt;br /&gt;
the ASCII-Latin1 character table.&lt;br /&gt;
Thus, &amp;lt;tt&amp;gt;%20&amp;lt;/tt&amp;gt; represents a space character, and&lt;br /&gt;
&amp;lt;tt&amp;gt;%&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;%0&amp;lt;/tt&amp;gt;, and &amp;lt;tt&amp;gt;%00&amp;lt;/tt&amp;gt; all represent an empty string value;&lt;br /&gt;
&amp;lt;tt&amp;gt;%%&amp;lt;/tt&amp;gt; represents the &amp;lt;tt&amp;gt;%&amp;lt;/tt&amp;gt; character itself.&lt;br /&gt;
The line&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Demo string SomeString= a%20string%20with%20spaces % % %&lt;br /&gt;
    // White space example&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
defines a parameter &#039;&#039;SomeString&#039;&#039;  which contains the value&lt;br /&gt;
&#039;&#039;a string&lt;br /&gt;
with spaces&#039;&#039;. &lt;br /&gt;
The single &amp;lt;tt&amp;gt;%&amp;lt;/tt&amp;gt; characters indicate that the &lt;br /&gt;
&#039;&#039;DefaultValue&#039;&#039; ,&lt;br /&gt;
&#039;&#039;LowRange&#039;&#039;  and &#039;&#039;HighRange&#039;&#039;  fields should be empty&lt;br /&gt;
strings.&lt;br /&gt;
&lt;br /&gt;
==Sub-parameters==&lt;br /&gt;
Any parameter value may itself be a sub-parameter.&lt;br /&gt;
Sub-parameters are represented by a short-form&lt;br /&gt;
matrix definition omitting the &#039;&#039;Section&#039;&#039;  and &#039;&#039;Name&#039;&#039; &lt;br /&gt;
fields, enclosed in&lt;br /&gt;
a pair of braces:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Demo matrix NestedMatrices= 1 2 11 { matrix 2 2 1211 1212 1221 1222 }&lt;br /&gt;
    // Nested matrix example&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
will define a matrix parameter whose 1,2 entry is a 2x2 matrix.&lt;br /&gt;
While the syntax allows for any combination of parameter and&lt;br /&gt;
subparameter types,&lt;br /&gt;
the current implementation of the parameter editor GUI only&lt;br /&gt;
supports matrix-type&lt;br /&gt;
sub-parameters within matrices as in the example above.&lt;br /&gt;
&lt;br /&gt;
==Display Format==&lt;br /&gt;
Generally, a parameter&#039;s &amp;lt;tt&amp;gt;DataType&amp;lt;/tt&amp;gt; field will be used to &lt;br /&gt;
determine its appropriate display in a parameter editor.&lt;br /&gt;
However, often a more user-friendly display may be achieved if &lt;br /&gt;
additional information about a parameter&#039;s content is available.&lt;br /&gt;
&lt;br /&gt;
To allow for such information, the comment line that is introduced by the&lt;br /&gt;
two&lt;br /&gt;
slashes (//) may contain a format identifier that is used by the&lt;br /&gt;
Operator module&lt;br /&gt;
to modify the display of the particular parameter. Format identifiers&lt;br /&gt;
are&lt;br /&gt;
strictly optional and are introduced as follows:&lt;br /&gt;
&amp;lt;tt&amp;gt;(identifier)&amp;lt;/tt&amp;gt;.&lt;br /&gt;
Currently, the following format identifiers are implemented:&lt;br /&gt;
&lt;br /&gt;
{| border=&amp;quot;1&amp;quot;&lt;br /&gt;
|+ The currently defined format identifiers&lt;br /&gt;
! Identifier !! Description&lt;br /&gt;
|- &lt;br /&gt;
| &amp;lt;tt&amp;gt;(enumeration)&amp;lt;/tt&amp;gt; || a choice from an enumerated set of values&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;(boolean)&amp;lt;/tt&amp;gt; || a yes/no choice &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;(inputfile)&amp;lt;/tt&amp;gt; || path to a file to be opened for reading &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;(outputfile)&amp;lt;/tt&amp;gt; || path to a file to be opened for writing &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;(directory)&amp;lt;/tt&amp;gt; || path to a directory &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;(color)&amp;lt;/tt&amp;gt; || RGB color &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===&amp;lt;tt&amp;gt;(enumeration)&amp;lt;/tt&amp;gt;===&lt;br /&gt;
The parameter value is presented as a drop down menu, with entries&lt;br /&gt;
corresponding to the&lt;br /&gt;
possible values listed in the comment. The first part of the comment&lt;br /&gt;
appears above&lt;br /&gt;
the drop down menu. All interpunction characters present in the&lt;br /&gt;
comment are ignored.&lt;br /&gt;
The data type of the parameter must be &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;.&lt;br /&gt;
All possible values must appear in the comment, and the parameter&#039;s&lt;br /&gt;
LowRange and HighRange &lt;br /&gt;
fields must be consistent with the enumeration. LowRange will usually&lt;br /&gt;
be 0, but may be any&lt;br /&gt;
integer. For example: &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Breakfast int BreakfastDrink= 1 1 1 3&lt;br /&gt;
  // Drink for breakfast: 1 Tea, 2 Coffee, 3 Juice (enumeration)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
will display a drop down menu with entries &amp;quot;Tea,&amp;quot; &amp;quot;Coffee,&amp;quot;, and&lt;br /&gt;
&amp;quot;Juice.&amp;quot;&lt;br /&gt;
The menu will be labeled &amp;quot;Drink for breakfast.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
===&amp;lt;tt&amp;gt;(boolean)&amp;lt;/tt&amp;gt;===&lt;br /&gt;
The parameter value is presented as a check box; the first part of the&lt;br /&gt;
comment appears&lt;br /&gt;
to the right of the check box. LowRange and HighRange must be 0 and 1.&lt;br /&gt;
The parameter&#039;s data type must be &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;.&lt;br /&gt;
To ensure human readability of parameter files, the possible values&lt;br /&gt;
and their meaning may&lt;br /&gt;
appear in the comment (e. g. &amp;lt;tt&amp;gt;0: no, 1: yes&amp;lt;/tt&amp;gt;) but will not&lt;br /&gt;
be displayed with the&lt;br /&gt;
check box. For example:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Breakfast int ServeBreakfast= 1 1 0 1&lt;br /&gt;
  // Serve breakfast: 0 no, 1 yes (boolean)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
will display a check box labeled &amp;quot;Serve breakfast.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
===&amp;lt;tt&amp;gt;(inputfile)(outputfile)(directory)&amp;lt;/tt&amp;gt;===&lt;br /&gt;
The parameter value is presented as an edit field. Beside the edit&lt;br /&gt;
field, there is a button that opens up a file or directory and selects dialog when clicked.&lt;br /&gt;
The parameter&#039;s data type must be &amp;lt;tt&amp;gt;string&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Breakfast string WakeupSound= doorbell.wav &lt;br /&gt;
  // Sound to play in the morning (inputfile)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===&amp;lt;tt&amp;gt;(color)&amp;lt;/tt&amp;gt;===&lt;br /&gt;
The parameter value is presented as an edit field. To the right of the edit&lt;br /&gt;
field there is a button that opens up a color selector dialog when clicked.&lt;br /&gt;
The parameter&#039;s data type must be &amp;lt;tt&amp;gt;string&amp;lt;/tt&amp;gt;, with its value&lt;br /&gt;
containing the color&lt;br /&gt;
in hexadecimal RGB encoding:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Breakfast string TableClothColor= 0x00FF00 0xFFFFFF 0x000000 0xFFFFFF&lt;br /&gt;
  // Color of table cloth to put up for breakfast (color)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Grouping Parameters by Sections==&lt;br /&gt;
A user interface may use fields in the parameter &amp;lt;tt&amp;gt;Section&amp;lt;/tt&amp;gt; fields to&lt;br /&gt;
collect parameters into&lt;br /&gt;
groups, e.g., by displaying all parameters with identical section&lt;br /&gt;
fields on the same&lt;br /&gt;
register tab of a GUI parameter editor dialog window.&lt;br /&gt;
In the &amp;lt;tt&amp;gt;Section&amp;lt;/tt&amp;gt; field, finer grained grouping may be expressed&lt;br /&gt;
by specifying&lt;br /&gt;
sub-sections separated by colon characters, e.g., a &amp;lt;tt&amp;gt;Section&amp;lt;/tt&amp;gt;&lt;br /&gt;
value of&lt;br /&gt;
&amp;lt;font color=&amp;quot;#cd4b19&amp;quot;&amp;gt;UsrTask:WindowDimensions&amp;lt;/font&amp;gt;&lt;br /&gt;
will indicate that a parameter belongs to a &amp;lt;tt&amp;gt;WindowDimensions&amp;lt;/tt&amp;gt;&lt;br /&gt;
subsection of&lt;br /&gt;
a section called &amp;lt;tt&amp;gt;UsrTask&amp;lt;/tt&amp;gt;. A parameter editor implementation&lt;br /&gt;
might display the respective parameter on a register tab called&lt;br /&gt;
&amp;quot;UsrTask&amp;quot; and&lt;br /&gt;
inside a group box labelled &amp;quot;WindowDimensions&amp;quot;.&lt;br /&gt;
Although any number of sub-sections may be present in the&lt;br /&gt;
&amp;lt;tt&amp;gt;Section&amp;lt;/tt&amp;gt; field,&lt;br /&gt;
a user interface implementation may ignore sub-section entries below a&lt;br /&gt;
level chosen by the implementer.&lt;br /&gt;
-----&lt;br /&gt;
See also: [[User Reference:Parameters]]&lt;/div&gt;</summary>
		<author><name>Atennissen</name></author>
	</entry>
	<entry>
		<id>https://www.bci2000.org/mediawiki/index.php?title=Technical_Reference:BCI2000_Messages&amp;diff=1779</id>
		<title>Technical Reference:BCI2000 Messages</title>
		<link rel="alternate" type="text/html" href="https://www.bci2000.org/mediawiki/index.php?title=Technical_Reference:BCI2000_Messages&amp;diff=1779"/>
		<updated>2007-05-09T19:17:25Z</updated>

		<summary type="html">&lt;p&gt;Atennissen: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Information transferred between BCI2000 modules is packed into messages.&lt;br /&gt;
Each message content corresponds to a BCI2000 data type such as Parameter, State, or Signal, and is wrapped into a layer that allows for routing the message to an appropriate handler.&lt;br /&gt;
BCI2000 data types know how to write themselves to, and read themselves from, a data stream.&lt;br /&gt;
For example, when the wrapper indicates that a message contains a brain signal, the framework code will route the message to a &amp;quot;brain signal&amp;quot; handler function that, in turn, asks a brain signal object to read itself from the message.&lt;br /&gt;
As another example, when the operator module receives a visualization message, the message wrapper layer will not only be used to direct the message to a visualization handler but also to the visualization window to which the message is addressed.&lt;br /&gt;
&lt;br /&gt;
===Protocol Definition===&lt;br /&gt;
Each message starts&lt;br /&gt;
with a one-byte content descriptor and a one-byte descriptor supplement, followed&lt;br /&gt;
by a number that describes the length of the content. (See Figure below)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Image:BCI2000_Messages_MessageProtocol.png|center|thumb|400px|Layout of one message in the protocol.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The element denoted by &amp;quot;length field(2)&amp;quot; was originally a two-byte integer&lt;br /&gt;
field for the content length in little endian format. To allow for messages&lt;br /&gt;
longer than 64k, we introduced a backwards-compatible extension: if the length&lt;br /&gt;
is below 65535, it will still be transmitted as a two-byte integer in little&lt;br /&gt;
endian format. Otherwise, the two bytes will contain the value 65535, and be&lt;br /&gt;
followed by a decimal ASCII representation of the length, terminated with a zero&lt;br /&gt;
byte. For other one- and two-byte length fields occurring in the protocol, the&lt;br /&gt;
same scheme applies, generalized to be a &amp;quot;length field (original number of bytes)&amp;quot;. (See Figure below)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Image:BCI2000_Messages_LengthField.png|center|thumb|300px|Detailed layout of a length field (m) for a length &amp;lt;math&amp;gt;n \geq 2^{m}-1&amp;lt;/math&amp;gt;]]&lt;br /&gt;
&lt;br /&gt;
{| border=&amp;quot;1&amp;quot; cellpadding=&amp;quot;2&amp;quot;&lt;br /&gt;
|+&lt;br /&gt;
&lt;br /&gt;
===Overview of Content Descriptors===&lt;br /&gt;
!descriptor  !! description  &lt;br /&gt;
|-&lt;br /&gt;
| 1 || status information string &lt;br /&gt;
|-&lt;br /&gt;
| 2 || system parameter &lt;br /&gt;
|-&lt;br /&gt;
| 3 || system state &lt;br /&gt;
|-&lt;br /&gt;
| 4 || visualization data or brain signal&lt;br /&gt;
|-&lt;br /&gt;
| 5 || state vector &lt;br /&gt;
|-&lt;br /&gt;
| 6 || system command &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Descriptor=1: Status Information Format===&lt;br /&gt;
This section describes the format of the message when the core message is&lt;br /&gt;
a status information string (i.e., the message&#039;s descriptor is 1). In this&lt;br /&gt;
case, the aforementioned content data is a line of ASCII characters in the following format:&lt;br /&gt;
 xxx: status-line-text&lt;br /&gt;
xxx is a three digit number that describes the content of the status&lt;br /&gt;
information string.&lt;br /&gt;
A first digit of `1&#039; indicates status information, a first digit of `2&#039; indicates successful&lt;br /&gt;
operation, a first digit of `3&#039; indicates recoverable errors and a first digit of `4&#039; indicates fatal errors. The two remaining digits define the exact nature of the message, followed by a plain description.&lt;br /&gt;
This procedure is used to communicate errors and to convey status&lt;br /&gt;
information (e.g.,&lt;br /&gt;
the operator module may display the remaining disc space on the machine of the Source module.)&lt;br /&gt;
&lt;br /&gt;
===Descriptor=2: Parameter Format===&lt;br /&gt;
For parameter messages, content data is a line of ASCII characters &lt;br /&gt;
representing a [[parameter definition]] line.&lt;br /&gt;
&lt;br /&gt;
===Descriptor=3: State Format===&lt;br /&gt;
State messages contain a line of ASCII characters representing a &lt;br /&gt;
[[state definition]] line.&lt;br /&gt;
&lt;br /&gt;
===Descriptor=4: Visualization and Brain Signal Data Format===&lt;br /&gt;
This section describes the format of the message when the core message&lt;br /&gt;
is a visualization data/brain signal message (i.e., the descriptor on the message is 4). In this&lt;br /&gt;
case, the content descriptor describes the requested visualization type. &lt;br /&gt;
The currently defined types are 1 (a graph of &#039;&#039;n&#039;&#039;  channels and &#039;&#039;m&#039;&#039;  samples), 2 (a text memo), and 255 (visualization configuration).&lt;br /&gt;
For brain signals, the content descriptor is 1. (See Figure below) &lt;br /&gt;
&lt;br /&gt;
[[Image:BCI2000_Messages_VisualizationData.png|center|thumb|500px|One message in the protocol of type &amp;quot;visualization data&amp;quot;.]]&lt;br /&gt;
&lt;br /&gt;
 &lt;br /&gt;
The following figure illustrates the protocol when the visualization type is 1. The source identifier defines a unique number identifying the process/filter that generated the data. The data type&lt;br /&gt;
can be   &lt;br /&gt;
*0 &amp;lt;tt&amp;gt;(SignalType::int16)&amp;lt;/tt&amp;gt; for integers in little endian format. &lt;br /&gt;
*1 &amp;lt;tt&amp;gt;(SignalType::float24)&amp;lt;/tt&amp;gt; for 3-byte floating-point values: The first two bytes (i.e., A) define the mantissa (signed two-byte integers in little endian format) and the third byte (i.e., B) defines the exponent (signed one-byte integer). The actual floating point value is then calculated as follows: &amp;lt;math&amp;gt;value=A*10^{B}&amp;lt;/math&amp;gt;. &lt;br /&gt;
*2 &amp;lt;tt&amp;gt;(SignalType::float32)&amp;lt;/tt&amp;gt; for 4-byte floating-point values in IEEE 754 format transmitted in little endian byte order. &lt;br /&gt;
*3 &amp;lt;tt&amp;gt;(SignalType::int32)&amp;lt;/tt&amp;gt; for 4-byte signed integer values transmitted in little endian byte order. &lt;br /&gt;
&lt;br /&gt;
The number of channels and samples are self explanatory.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Image:BCI2000_Messages_vistype1(graph).png|center|thumb|600px|One message if the visualization type is 1 (i.e., a graph).]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The following figure illustrates how the data is transferred.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Image:BCI2000_Messages_TransmittedVisualizationDataFormat.png|center|thumb|500px|Graphical representation of the transmitted visualization data format.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The following figure illustrates the protocol when the visualization type is 2. The source identifier is a number uniquely identifying the process/filter that generated the data. (0 for brain signals.)&lt;br /&gt;
The following ASCII text is zero delimited.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Image:BCI2000_Messages_vistype2(memo).png|center|thumb|400px|One message if the visualization type is 2 (i.e., a text memo).]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The following figure illustrates the protocol when the visualization type is 255. The source identifier is a number identifying the process/filter that generated the data. The different configuration IDs are defined in the CFGID enumeration in the  [http://www.bci2000.org/tracproj/browser/trunk/src/shared/defines.h shared/defines.h]&lt;br /&gt;
header file.&lt;br /&gt;
&lt;br /&gt;
The ASCII string then contains the configuration option, as defined by the configuration ID. For example, it might contain &amp;quot;128&amp;quot; if the configuration ID is 4. This will configure the graph to contain exactly 128 samples. When the configuration ID is 5 or 6 (axis labels), the ASCII string consists of a sample number (three digits), a space, and the axis label. Thus, one message&lt;br /&gt;
configures exactly one axis label. As an example, for an X-axis label, the string &amp;quot;003 4.75 Hz&amp;quot; would result in a graph, in which the third sample is labeled &amp;quot;4.75 Hz.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Image:BCI2000_Messages_vistype255(visconfig).png|center|thumb|500px|One message if the visualizationtype is 255 (i.e., visualization configuration).]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====Brain Signal Format====&lt;br /&gt;
The brain signal is transmitted similarly to visualization data (i.e., as described in the Visualization and Brain Signal Data Format above). The visualization type is set to 1 (i.e., graph), source identifier is set to 0. Data type, channels and samples reflect the actual format of data transmitted.&lt;br /&gt;
&lt;br /&gt;
====Control Signal Format====&lt;br /&gt;
Control signals are transmitted identically to the Brain Signal.&lt;br /&gt;
&lt;br /&gt;
===Descriptor=5: State Vector===&lt;br /&gt;
The state vector is defined by a series of &#039;&#039;StateVectorLength&#039;&#039; &lt;br /&gt;
subsequent bytes.&lt;br /&gt;
The value of a given state within the state vector is determined by&lt;br /&gt;
its byte/bit&lt;br /&gt;
location and length definition. The bits in the state vector are&lt;br /&gt;
always sorted&lt;br /&gt;
in ascending order, e.g., for a state with a length of 7 bits,&lt;br /&gt;
starting at byte&lt;br /&gt;
location 2, bit location 3, bit zero is first (byte 2, bit 3), and the&lt;br /&gt;
highest&lt;br /&gt;
bit (bit 7) is last (byte 3, bit 1).&lt;br /&gt;
&lt;br /&gt;
===Descriptor=6: System Command===&lt;br /&gt;
The system command consists of an ASCII string that may end with a&lt;br /&gt;
zero byte (i.e., ASCII code 0).&lt;br /&gt;
The nature of these system commands is defined by the specific&lt;br /&gt;
implementation of&lt;br /&gt;
the modules.&lt;/div&gt;</summary>
		<author><name>Atennissen</name></author>
	</entry>
	<entry>
		<id>https://www.bci2000.org/mediawiki/index.php?title=MARIO_Technical_Documentation&amp;diff=1778</id>
		<title>MARIO Technical Documentation</title>
		<link rel="alternate" type="text/html" href="https://www.bci2000.org/mediawiki/index.php?title=MARIO_Technical_Documentation&amp;diff=1778"/>
		<updated>2007-05-09T19:14:20Z</updated>

		<summary type="html">&lt;p&gt;Atennissen: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==MARIO Architecture==&lt;br /&gt;
MARIO is an off-line analysis application developed in MATLAB 7.0.2. It is now modular, object-oriented and can be easily integrated with any other software for data analysis and visualization.&lt;br /&gt;
It can be used in Mu and P300 analyses and allows three kinds of use: users can simply fill the forms of a graphical interface making any choice with a click of its mouse, run a ready-made script or, write up their own scripts according to their needs.&lt;br /&gt;
This set of interfaces allows a wide range of possibilities for a wide range of different analyses.&lt;br /&gt;
&lt;br /&gt;
Internally, the application is composed of 6 main functional modules, each one connected in cascade as in the list below:&lt;br /&gt;
&lt;br /&gt;
*Data import&lt;br /&gt;
*Signal Conditioning&lt;br /&gt;
*Feature Extraction&lt;br /&gt;
*Spectral Extimation&lt;br /&gt;
*Statistical Analysis&lt;br /&gt;
*Visualization&lt;br /&gt;
&lt;br /&gt;
[[Image:arch_blocks.jpg]]&lt;br /&gt;
&lt;br /&gt;
All these modules are hidden in the graphical user interface but they can be distinguished in the batch scripts. Each one of them can be easily replaced with an improved version, a custom version or a different analysis.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Image:Graph.png|thumb|left|Graph of modules]] &lt;br /&gt;
Here you can see a &amp;lt;b&amp;gt;simplified version of the functions graph with their relationships (click to enlarge). &amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Data Import Module==&lt;br /&gt;
&lt;br /&gt;
Any script must have a first module in which to load data that the user wants to analyze.&lt;br /&gt;
There are 3 main types of files containing different groups of information:&lt;br /&gt;
&lt;br /&gt;
*Data files (.dat/.mat)&lt;br /&gt;
*Montage files (.mmf)&lt;br /&gt;
*External Parameter files (.prm) – optional&lt;br /&gt;
&lt;br /&gt;
The data files contain all the data of the BCI session (Mu or P300).&lt;br /&gt;
These data are saved in different files, one for each run, containing 29 trials.&lt;br /&gt;
Internally any file is divided in two main parts: the first part (file header) includes all parameters set by the operator  during the on-line experimentation; the second part contains the EEG signal recorded by the whole set of electrodes on the EEG cap.&lt;br /&gt;
A special function allows data to be loaded from a Matlab file (.mat).&lt;br /&gt;
&lt;br /&gt;
The montage file stores information about the electrode position on the scalp. It consists &lt;br /&gt;
of different sections divided by labels:&lt;br /&gt;
&lt;br /&gt;
#a synthetic name&lt;br /&gt;
#the channel labels&lt;br /&gt;
#a valid channels list&lt;br /&gt;
#the laplacian grid&lt;br /&gt;
#the 3-dimensional spatial coordinates of all the electrodes (this section is optional)&lt;br /&gt;
&lt;br /&gt;
These labelled sections  can be written in the Montage file without a predefined order.&lt;br /&gt;
&lt;br /&gt;
The user can import data from an additional data file, (a parameters file), that can be used if he wants to replace one or more parameters from the BCI2000 ones. For this, it is enough to copy and paste the selected header string in a new prm file, and change its value. &lt;br /&gt;
&lt;br /&gt;
This module is clearly the same for Mu and P300 Analysis.&lt;br /&gt;
&lt;br /&gt;
==Data Conditioning Module==&lt;br /&gt;
&lt;br /&gt;
The MARIO v.2.0 Data Conditioning module allows users to select from a wide range of spatial filters so as to include a custom filter in the user data analysis. The operator can identify which channels or set of channels will give better results at the end of the statistical analysis.&lt;br /&gt;
&lt;br /&gt;
For a Mu analysis, the user can select from four different spatial filter algorithms:&lt;br /&gt;
&lt;br /&gt;
*RAW&lt;br /&gt;
*CAR (Common Average Reference)&lt;br /&gt;
*SMALL LAP&lt;br /&gt;
*LARGE LAP&lt;br /&gt;
&lt;br /&gt;
The first one, (RAW) does not use a filter and analyzes raw recorded data. A user defined analysis will be available on further versions of MARIO.&lt;br /&gt;
&lt;br /&gt;
The Data Conditioning module also allows the the user to compile/modify a list of valid channels on which to conduct any analysis. &lt;br /&gt;
&lt;br /&gt;
P300 Analysis can now use only two of the above spatial filters: the RAW filter and the CAR one. Any other selection will report an unhandled error.&lt;br /&gt;
&lt;br /&gt;
==Feature Extraction Module==&lt;br /&gt;
&lt;br /&gt;
Feature extraction is one of the most important stages of elaboration; it affects any further analysis.&lt;br /&gt;
&lt;br /&gt;
In a Mu rhythm analysis, any feature can be obtained by arranging some of the 12 BCI2000 states.&lt;br /&gt;
The user can now make a choice between two predefined analyses, a simple Mu analysis or an Extended version of the same. The first analysis considers any sample recorded between the cursor appearance on the screen and the end of the trial (when the cursor reaches the right side of the screen).&lt;br /&gt;
The MuExteded analysis instead considers any sample recorded since the target appearance (during the first subset of data, the subject does not have any feedback) until the end of trial.&lt;br /&gt;
In both choices, the statistical analysis will be conduced between two classes of data: the EEG activity recorded while moving up the cursor  (target UP) versus the EEG activity recorded while moving down the cursor (target DOWN).&lt;br /&gt;
Either of these choices will produce different R&amp;lt;sup&amp;gt;2&amp;lt;/sup&amp;gt; values between the corresponding features of the two classes&lt;br /&gt;
&lt;br /&gt;
For a P300 Analysis only two classes are compared and automatically set as frequent events and rare events.&lt;br /&gt;
&lt;br /&gt;
==Spectral Extimation Module &#039;&#039;(for Mu rhythm analysis)&#039;&#039;==&lt;br /&gt;
&lt;br /&gt;
During this step, the program evaluates and analyzes the spectrum of recorded data. &lt;br /&gt;
To do that, the EEG signal is divided into equal length epochs (These epochs can be distinct or overlapped as a percentage of overlap, which the user can set by using the Graphical User Interface or script.)  A spectrum value is evaluated for anyone of these epochs.&lt;br /&gt;
&lt;br /&gt;
At the end of this process, a 3 dimensional matrix (bin × channel × epoch) joined with the one (channel × sample) compiled during a BCI2000 recording session and read by the data import module will be produced.&lt;br /&gt;
&lt;br /&gt;
The algorithm employed to estimate the signal spectrum is the MEM (the same used on-line by BCI2000).&lt;br /&gt;
&lt;br /&gt;
Apart from the percentage of overlap, MARIO allows the user to modify the values of:&lt;br /&gt;
&lt;br /&gt;
#Sampling frequency of recorded data&lt;br /&gt;
#Spatial resolution (delta)&lt;br /&gt;
#Detrending order (Mean or Linear)&lt;br /&gt;
#AR model order&lt;br /&gt;
#Low pass filter frequency&lt;br /&gt;
#High pass filter frequency&lt;br /&gt;
#Filter bandwidth&lt;br /&gt;
#Epoch length&lt;br /&gt;
#Overlap percentage&lt;br /&gt;
&lt;br /&gt;
MARIO v2.0 also computes a virtual states matrix strictly joined with signal one and derived as an arrangement of the BCI2000 states. These states label spectrum samples as valid or not valid and as belonging to one class or another.&lt;br /&gt;
&lt;br /&gt;
==Statistical Analysis Module==&lt;br /&gt;
&lt;br /&gt;
A statistical analysis (presently, R&amp;lt;sup&amp;gt;2&amp;lt;/sup&amp;gt;)  is employed to distinguish between the classes of a BCI2000 task in any trial.&lt;br /&gt;
&lt;br /&gt;
MARIO uses a module that computes the R&amp;lt;sup&amp;gt;2&amp;lt;/sup&amp;gt; value between two classes; these can be TargetUP and TargetDOWN for a Mu rhythm analysis, or frequent events and rare events for a P300 analysis. These data are taken from the spectra matrix (Mu analysis) or from the samples one (P300 analysis) and the regressor vector is yield from BCI2000 states.&lt;br /&gt;
	&lt;br /&gt;
At the end of this analysis, the real index produced (in a range between -1 and 1) is the R&amp;lt;sup&amp;gt;2&amp;lt;/sup&amp;gt; value multiplied by R&amp;lt;sup&amp;gt;2&amp;lt;/sup&amp;gt; sign. If the R&amp;lt;sup&amp;gt;2&amp;lt;/sup&amp;gt; value is near 1, there is an high separability between classes and high performance. If, instead, its value is near 0, it is difficult to distinguish one class from another, and it means low performance.&lt;br /&gt;
&lt;br /&gt;
==Visualization Module==&lt;br /&gt;
&lt;br /&gt;
Mario offers a wide set of visualization graphs that can be combined to have a complete visualization of produced data.&lt;br /&gt;
For a Mu rhythm analysis the user can request to visualize:&lt;br /&gt;
&lt;br /&gt;
#a trajectory plot showing the cursor position for any sample in a  trial BCI2000 as the user saw it on-line&lt;br /&gt;
#a matrix (channel × bin) where the R&amp;lt;sup&amp;gt;2&amp;lt;/sup&amp;gt; value of any feature is shown in a color tint. A colorbar shows the color range between -1 and 1&lt;br /&gt;
#Another panel showing a detail of the previous matrix. The upper topographic plot shows the R&amp;lt;sup&amp;gt;2&amp;lt;/sup&amp;gt; value for any channel in the selected bin of frequencies; the lower one is the spectrum of the selected channel for all the frequencies.&lt;br /&gt;
&lt;br /&gt;
For a P300 analysis the user can choose from:&lt;br /&gt;
&lt;br /&gt;
#An R&amp;lt;sup&amp;gt;2&amp;lt;/sup&amp;gt; matrix&lt;br /&gt;
#An amplitude waveform graph&lt;br /&gt;
#A topographic plot&lt;br /&gt;
#An ERP response graph&lt;br /&gt;
#A string prediction form.&lt;br /&gt;
&lt;br /&gt;
All these result visualizations can be easily included in any of the user scripts for custom analysis.&lt;/div&gt;</summary>
		<author><name>Atennissen</name></author>
	</entry>
	<entry>
		<id>https://www.bci2000.org/mediawiki/index.php?title=Mu_Rhythm_Off-line_Analysis_Tutorial&amp;diff=1777</id>
		<title>Mu Rhythm Off-line Analysis Tutorial</title>
		<link rel="alternate" type="text/html" href="https://www.bci2000.org/mediawiki/index.php?title=Mu_Rhythm_Off-line_Analysis_Tutorial&amp;diff=1777"/>
		<updated>2007-05-09T19:10:36Z</updated>

		<summary type="html">&lt;p&gt;Atennissen: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Starting an Analysis Session ==&lt;br /&gt;
&lt;br /&gt;
Every recording session has its own history. It is very difficult to say in advance what might happen during the recording. So we will assume that everything was perfect (the subject collaborated, no channel went lost, etc); later on we will consider the main causes of contamination, how to recognize it and what to do.&lt;br /&gt;
&lt;br /&gt;
If the recording session runs smoothly, you should now have in the folder &#039;&#039;\TestData\Data\Mu&#039;&#039;,   two files named &#039;&#039;ALFAS006R01.dat&#039;&#039; and &#039;&#039;ALFAS006R02.dat&#039;&#039;, corresponding to two of the eight runs usually recorded, respectively.&lt;br /&gt;
&lt;br /&gt;
Before you start the analysis you should locate the correct montage file on your hard disk. This is a file that describes the list of channels that were acquired. In this tutorial we will use &#039;&#039;Complete_Montage(suggested choice).mmf&#039;&#039;, which is located in the folder &#039;&#039;\TestData\Montage&#039;&#039;. If you need to edit the *.mmf file, check its data format.&lt;br /&gt;
&amp;lt; the of performances optimize that parameters try will we then online; performed BCI2000 analyses same off-line replicate to first&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Opening Files with Mario ==&lt;br /&gt;
&lt;br /&gt;
After having run mario.exe, press &amp;quot;Select Data Files&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
[[Image:Mu Rhy5.jpg]]&lt;br /&gt;
&lt;br /&gt;
A dialog window will ask you to select the dat files. You can either select a single data file, or select multiple files. This time, we will select all files in the dataset.&lt;br /&gt;
&lt;br /&gt;
A green box will surround the Raw Data box in the main window.&lt;br /&gt;
&lt;br /&gt;
As an optional (but recommended) operation, click on the LOAD MONTAGE button and choose the mmf file. This will allow you to see the labels of each channel and allow you to apply spatial filters that depend on the electrode position.&lt;br /&gt;
&lt;br /&gt;
You can load an additional parameters file with choices different from those used during the experiment.&lt;br /&gt;
&lt;br /&gt;
At this point, you can check that Mu is selected in the Analysis menu (indicating that a Mu dataset has been recognized) and click on the LOAD DATA button to confirm your choices. This will enable the EDIT CHANNEL LIST button that you can use to select the channels you want to include in your analysis.&lt;br /&gt;
&lt;br /&gt;
== Selecting Channels ==&lt;br /&gt;
&lt;br /&gt;
Pushing the the EDIT CHANNEL LIST button, two forms will show you the channels list (valids&#039; and not-valids&#039; one) and an image reassuming valid channels and their location.&lt;br /&gt;
&lt;br /&gt;
Clicking on Add and Remove buttons allows you to move a channel from one list to the other, enabling or disabling it.&lt;br /&gt;
&lt;br /&gt;
== Selecting the Spatial Filter ==&lt;br /&gt;
&lt;br /&gt;
Return to the main window, and you can choose which filter to apply for your analysis, selecting from the following filter choices:&lt;br /&gt;
&lt;br /&gt;
:*RAW&lt;br /&gt;
:*CAR&lt;br /&gt;
:*Large Laplacian&lt;br /&gt;
:*Small Laplacian&lt;br /&gt;
&lt;br /&gt;
Common Average Reference (CAR) will be fine for most of the situations.&lt;br /&gt;
&lt;br /&gt;
We hope, soon, to release a user defined solution for any custom analysis.&lt;br /&gt;
&lt;br /&gt;
== Feature Extraction Analysis ==&lt;br /&gt;
&lt;br /&gt;
The Analysis field in the Feature Extraction panel will appear automatically according to the files loaded, while the Feature Extractor field shows the only currently possible choice.&lt;br /&gt;
&lt;br /&gt;
You can view/edit analysis details by clicking on &amp;quot;Set Analysis Details&amp;quot; and &amp;quot;Set F.E. parameters&amp;quot;&lt;br /&gt;
&lt;br /&gt;
This second form reports all the settings for the parametric (autoregressive) spectral estimation stage. Most of the values are set after the corresponding values used on-line (see BCI2000 setup for Mu). Using the settings in the figure, the analysis software will:&lt;br /&gt;
&lt;br /&gt;
:*data recorded at 200 Hz sampling rate &lt;br /&gt;
:* remove the mean value &lt;br /&gt;
:* sample the spectrum at points starting from 0 Hz to 60 Hz, every 0.2 Hz. &lt;br /&gt;
:* Identify an auroregressive model of order 16 &lt;br /&gt;
:* average these values into 2 Hz wide bins &lt;br /&gt;
:* take a 1 s long epoch of data &lt;br /&gt;
&lt;br /&gt;
You can modify these settings according to your aims. Changing the model order, for instance, brings sometimes to interesting results. Remember though that in the online version, spectral estimation is performed in epochs as short as 200 ms (i.e. 40 samples, at 200 Hz sampling rate), so you should avoid using a model order higher than half the samples available in the epoch.&lt;br /&gt;
When you are finished, remember to confirm your choices by slecting DONE. &lt;br /&gt;
&lt;br /&gt;
In addition, a button in the Spectral Extimation frame allows you to revert to the original values. &lt;br /&gt;
&lt;br /&gt;
Altogether you have to specify:&lt;br /&gt;
&lt;br /&gt;
:* which data (in each trial) you want to take into account. Mu will only use the part of the trial when the cursor is visible, while MuExtended will take into account all the period when the target is visible. To learn more, see section D2Box Application States &lt;br /&gt;
:* If you have made an artifact rejection (or noted on the run sheet during the acquisition which trials contain artifacts), you can instruct the software not to use them&lt;br /&gt;
:* Finally, you must decide how the software must extract EEG epochs from the continuous data&lt;br /&gt;
The epochs can be partially overlapped. This attenuates the data loss in case the length of a trial is not a multiple of the length of an epoch.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The percentage of overlap can be set both in Mario GUI and in any batch script. It is equal to the value of the &#039;&#039;MU_params.overlapping&#039;&#039; variable and the corresponding GUI field can be found by clickiing on &#039;&#039;Set Analysis Details&#039;&#039; on MARIO main form.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
At this point you can start the analysis by clicking on the Evaluate and Plot button.&lt;br /&gt;
&lt;br /&gt;
[[Image:Mu Rhy8.jpg]]&lt;br /&gt;
&lt;br /&gt;
== View Results ==&lt;br /&gt;
&lt;br /&gt;
The first figure that appears is the R-square matrix (channels x frequency bins)&lt;br /&gt;
=== R-square Matrix ===&lt;br /&gt;
&lt;br /&gt;
The r-square matrix highlights the most relevant spectral features for the separation of the two classes of EEG - Cursor Up (target 1) and Cursor Down (target 2).&lt;br /&gt;
&lt;br /&gt;
[[Image:Mu Rhy8.jpg]]&lt;br /&gt;
&lt;br /&gt;
Each row of the matrix is related to a single channel, while a column represents a frequency bin (labeled with its central frequency). The color codes the statistical significance of the difference between the two kinds of evoked potentials.&lt;br /&gt;
&lt;br /&gt;
Thus a red color would mean that, on that channel and for that frequency, the &amp;quot;Up&amp;quot; EEG is significantly synchronized with respect to &amp;quot;Down&amp;quot; EEG.&lt;br /&gt;
&lt;br /&gt;
Clicking on a cell of the matrix will open two more windows:&lt;br /&gt;
&lt;br /&gt;
* Power spectral distribution of the selected channel&lt;br /&gt;
* Topographic maps at the selected frequency.&lt;br /&gt;
&lt;br /&gt;
You can choose whether to overwrite or to put the most recently evoked figures beside the previous one. Two sets of waveform/topography figures are available, and are linked to the click of the left, the central or right mouse button.&lt;br /&gt;
&amp;lt;b&amp;gt;Left Button&amp;lt;/b&amp;gt; will create/overwrite a first figure, &amp;lt;b&amp;gt;Right Button&amp;lt;/b&amp;gt; will do the same on a second figure, the &amp;lt;b&amp;gt;Central Button&amp;lt;/b&amp;gt; will always open a new plot.&lt;br /&gt;
&lt;br /&gt;
=== Power Spectra and Topographic Plots ===&lt;br /&gt;
&lt;br /&gt;
In the lower panel you can find the spectral density of power for both classes of EEG. The Blue line refers to the &amp;quot;Up&amp;quot; condition, while the Red line refers to the &amp;quot;Down&amp;quot; condition.&lt;br /&gt;
We can see that at the vertex the &amp;quot;Down&amp;quot; condition is generally more synchronized than the &amp;quot;Up&amp;quot;, with maximal difference in the beta band, consistently with what is shown by the R-square matrix.  The proportinality between spectral differences and R-square is anyway rough, since r-square is sensitive to the dispersion (variance) of single trials; thus, small differences between spectra could bring to a high r-square, if they were very reproducible.&lt;br /&gt;
&lt;br /&gt;
The peak around 50 Hz is due to mains disturbance; this also allows you to appreciate the leakage introduced by the spectral estimation.&lt;br /&gt;
&lt;br /&gt;
[[Image:Mu_Rhy9.jpg]]&lt;br /&gt;
&lt;br /&gt;
Over the spectral graph, a topographic plot shows the scalp distribution of the r-square.&lt;br /&gt;
&lt;br /&gt;
The color coding is the same as the r-square matrix figure, and values on each channel are interpolated to create a continuous bidimensional map. The higher the number of electrodes, the more accurate is the map. With Surface Laplacian spatial filtering, the number of channels shown on the scalp may not coincide with the whole number of electrodes, since the value of the laplacian is not computed on the border channels.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The first step in the preliminary analysis of P300 BCI data is to find the absolute maximum of r-square. This simple statement must be mediated with a proper knowledge of physiological phenomena. In fact, we do not expect any sensorimotor activity at 3 Hz, so if the absolute maximum is at that frequency, you must suspect that it is actually an artifact. The same holds true if the spatial localization of the peak is far away from the centro-parietal electrodes.&lt;br /&gt;
&lt;br /&gt;
From a practical point of view, it is not important, now, to understand the reasons different component that explain the desynchrinization peak on Cz at 17 Hz, as far as we are confident that this component is stable enough to be exploitable during the next session to control the cursor.&lt;br /&gt;
&lt;br /&gt;
The absolute value of R-square is mathematically bound to lie in the interval between 0 and 1. Values above 0.4 allow a rate of missed target on the order of a few percent. Values around 0.1 are promising. Values below 0.03 are possibly due to random fluctuations. All the previous figures are referred to analyses made on 240 trials.&lt;br /&gt;
&#039;&#039;&amp;lt;b&amp;gt;Beware of artifacts!&amp;lt;/b&amp;gt;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
During the acquisition, you should be particularly careful to avoid artifacts. While EOG and blink artifacts are confined to very low frequencies, EMG artifacts are mostly on the beta band and could largely overlap with the frequency band that characterizes the mu rhythm.&lt;br /&gt;
&lt;br /&gt;
If contaminated data was acquired, then you have two problems:&lt;br /&gt;
&lt;br /&gt;
:* Realize that EMG is superimposed on the to data&lt;br /&gt;
:* Distinguish between spectral modulation introduced by EEG and by EMG &lt;br /&gt;
&lt;br /&gt;
The first task is not as trivial as it might appear. If you did not acquire the data yourself (or even if you did) you might complete the analysis procedure without giving a single glance to the raw data. So you must be particularly careful when you analyze the R-square maps, and always check if the peak you are seeing might be due to an artifact.&lt;br /&gt;
&lt;br /&gt;
Discriminant features between EEG and EMG are both in the frequency distribution and in the spatial distribution.&lt;br /&gt;
&lt;br /&gt;
EMG that strongly affects the recordings is mostly generated by muscles at the forehead or close to the ears/jaws. Thus, their spatial distribution is such that the most responsive channel is one of those at the border of the montage. Of course, due to volume conduction, the effects can be seen even on electrodes on the opposite part of the montage, but they show a degrading pattern.&lt;br /&gt;
On the other hand, a peak that shows its maximum on a central channel, can hardly be generated by a muscle or by other non-cephalic source.&lt;br /&gt;
&lt;br /&gt;
The spectrum of EEG is mainly concentrated in the alpha band, with a possible flatter and lower peak in beta. With the exception of the beta peak/plateau, the EEG spectrum decreases almost linearly (if measured in dB) after 12 Hz.&lt;br /&gt;
On the other hand, the EMG spectrum becomes significant at about 20 Hz and is still very high at the highest frequencies we usually analyze (60 Hz). A spectrum with a pattern more similar to the latter, may indicate that non-EEG activity is present in the data.&lt;br /&gt;
&lt;br /&gt;
==Improving the Analysis==&lt;br /&gt;
&lt;br /&gt;
The first cause of an unsuccessful analysis is  poor quality of the recording. For this reason it is highly recommended that, at least for the first experiments, the subject be highly motivated and cooperative. If this is the case, data of low quality are usually present in one or a few runs. And if the experimenter is careful enough, he/she should have noted the occurrence of strong artifacts on the run sheet.&lt;br /&gt;
In this case, the next step is to repeat an unsatisfactory data analysis after having excluded the (putative) bad runs.&lt;br /&gt;
To do this, just go back to the file selection dialog, choose LOAD Data again and load only the runs that you believe are clean. The number of runs should not be too low (as a rule of thumb, the data set should contain at least 100 trials), otherwise the r-square statistical analysis would loose sensitivity.&lt;br /&gt;
&lt;br /&gt;
== Analyzing the Screening ==&lt;br /&gt;
&lt;br /&gt;
The screening experiment is not different from a regular training session, from the point of view of data format. You will have four sets (horizontal movement, horizontal imagination, vertical movement, and vertical imagination) of three runs, containing EEG acquired in two conditions (up and down, or left and right).&lt;br /&gt;
&lt;br /&gt;
Start analyzing the vertical movement execution, and mark a few possible responsive features. The analysis on the vertical movement imagination should confirm (though with a lower R-square) those that are actually related to sensorimotor cognitive states.&lt;br /&gt;
&lt;br /&gt;
In the case that no reliable responsive EEG feature is found, the analysis can be repeated on the horizontal dataset.&lt;br /&gt;
&lt;br /&gt;
If both the vertical and horizontal dataset show responsive features, and these are different, the subject should be trained for some session on the vertical training until he/she decreases the false positive below 10%; at that point, the training of the horizontal modulation can begin, with the aim that, at a certain point, the subject can control both the vertical and the horizontal simultaneously in a two-dimensional task.&lt;br /&gt;
&lt;br /&gt;
==Conclusions==&lt;br /&gt;
&lt;br /&gt;
If you are confident that you have found a significant difference between conditions that is due to EEG rather than an artifact, and that reflects a cognitive process that is likely to be reproduced (or even enhanced with training) in the next session, you have reached your goal.&lt;br /&gt;
The next time the same subject practices with the D2Box Application, you will have to change the MUD matrix so that it reflects the feature that you just outlined.&lt;br /&gt;
&lt;br /&gt;
==Troubleshooting==&lt;br /&gt;
&lt;br /&gt;
Some OpenGL drivers may sometimes show defective figures like the following:&lt;br /&gt;
&lt;br /&gt;
[[Image:Defective.jpg]]&lt;br /&gt;
&lt;br /&gt;
Matlab customers can get around this problem using this simple procedure:&lt;br /&gt;
:* Select the defective figure window&lt;br /&gt;
:* Go to the Matlab Command Window&lt;br /&gt;
:* Execute one of the following command line:&lt;br /&gt;
:**set(gcf, &#039;Renderer&#039;, &#039;Painters&#039;) &lt;br /&gt;
:**set(gcf, &#039;Renderer&#039;, &#039;zbuffer&#039;)&lt;br /&gt;
&lt;br /&gt;
The figure will be a plot using a different renderer (Painters or zBuffer).&lt;/div&gt;</summary>
		<author><name>Atennissen</name></author>
	</entry>
	<entry>
		<id>https://www.bci2000.org/mediawiki/index.php?title=Mu_Rhythm_Off-line_Analysis_Tutorial&amp;diff=1776</id>
		<title>Mu Rhythm Off-line Analysis Tutorial</title>
		<link rel="alternate" type="text/html" href="https://www.bci2000.org/mediawiki/index.php?title=Mu_Rhythm_Off-line_Analysis_Tutorial&amp;diff=1776"/>
		<updated>2007-05-09T18:57:48Z</updated>

		<summary type="html">&lt;p&gt;Atennissen: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Starting an analysis session ==&lt;br /&gt;
&lt;br /&gt;
Every recording session has its own history. It is very difficult to say in advance what might happen during the recording. So we will assume that everything was perfect (the subject collaborated, no channel went lost, etc); later on we will consider the main causes of contamination, how to recognize it and what to do.&lt;br /&gt;
&lt;br /&gt;
If the recording session runs smoothly, you should now have in the folder &#039;&#039;\TestData\Data\Mu&#039;&#039;,   two files named &#039;&#039;ALFAS006R01.dat&#039;&#039; and &#039;&#039;ALFAS006R02.dat&#039;&#039;, corresponding to two of the eight runs usually recorded, respectively.&lt;br /&gt;
&lt;br /&gt;
Before you start the analysis you should locate the correct montage file on your hard disk. This is a file that describes the list of channels that were acquired. In this tutorial we will use &#039;&#039;Complete_Montage(suggested choice).mmf&#039;&#039;, which is located in the folder &#039;&#039;\TestData\Montage&#039;&#039;. If you need to edit the *.mmf file, check its data format.&lt;br /&gt;
&amp;lt; the of performances optimize that parameters try will we then online; performed BCI2000 analyses same off-line replicate to first&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Opening files with Mario ==&lt;br /&gt;
&lt;br /&gt;
After having run mario.exe, press &amp;quot;Select Data Files&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
[[Image:Mu Rhy5.jpg]]&lt;br /&gt;
&lt;br /&gt;
A dialog window will ask you to select the dat files. You can either select a single data file, or select multiple files. This time, we will select all files in the dataset.&lt;br /&gt;
&lt;br /&gt;
A green box will surround the Raw Data box in the main window.&lt;br /&gt;
&lt;br /&gt;
As an optional (but recommended) operation, click on the LOAD MONTAGE button and choose the mmf file. This will allow you to see the labels of each channel and allow you to apply spatial filters that depend on the electrode position.&lt;br /&gt;
&lt;br /&gt;
You can load an additional parameters file with choices different from those used during the experiment.&lt;br /&gt;
&lt;br /&gt;
At this point, you can check that Mu is selected in the Analysis menu (indicating that a Mu dataset has been recognized) and click on the LOAD DATA button to confirm your choices. This will enable the EDIT CHANNEL LIST button that you can use to select the channels you want to include in your analysis.&lt;br /&gt;
&lt;br /&gt;
== Selecting Channels ==&lt;br /&gt;
&lt;br /&gt;
Pushing the the EDIT CHANNEL LIST button, two forms will show you the channels list (valids&#039; and not-valids&#039; one) and an image reassuming valid channels and their location.&lt;br /&gt;
&lt;br /&gt;
Clicking on Add and Remove buttons allows you to move a channel from one list to the other, enabling or disabling it.&lt;br /&gt;
&lt;br /&gt;
== Selecting the Spatial Filter ==&lt;br /&gt;
&lt;br /&gt;
Return to the main window, and you can choose which filter to apply for your analysis, selecting from the following filter choices:&lt;br /&gt;
&lt;br /&gt;
:*RAW&lt;br /&gt;
:*CAR&lt;br /&gt;
:*Large Laplacian&lt;br /&gt;
:*Small Laplacian&lt;br /&gt;
&lt;br /&gt;
Common Average Reference (CAR) will be fine for most of the situations.&lt;br /&gt;
&lt;br /&gt;
We hope, soon, to release a user defined solution for any custom analysis.&lt;br /&gt;
&lt;br /&gt;
== Feature Extraction Analysis ==&lt;br /&gt;
&lt;br /&gt;
The Analysis field in the Feature Extraction panel will appear automatically according to the files loaded, while the Feature Extractor field shows the only currently possible choice.&lt;br /&gt;
&lt;br /&gt;
You can view/edit analysis details by clicking on &amp;quot;Set Analysis Details&amp;quot; and &amp;quot;Set F.E. parameters&amp;quot;&lt;br /&gt;
&lt;br /&gt;
This second form reports all the settings for the parametric (autoregressive) spectral estimation stage. Most of the values are set after the corresponding values used on-line (see BCI2000 setup for Mu). Using the settings in the figure, the analysis software will:&lt;br /&gt;
&lt;br /&gt;
:*data recorded at 200 Hz sampling rate &lt;br /&gt;
:* remove the mean value &lt;br /&gt;
:* sample the spectrum at points starting from 0 Hz to 60 Hz, every 0.2 Hz. &lt;br /&gt;
:* Identify an auroregressive model of order 16 &lt;br /&gt;
:* average these values into 2 Hz wide bins &lt;br /&gt;
:* take a 1 s long epoch of data &lt;br /&gt;
&lt;br /&gt;
You can modify these settings according to your aims. Changing the model order, for instance, brings sometimes to interesting results. Remember though that in the online version, spectral estimation is performed in epochs as short as 200 ms (i.e. 40 samples, at 200 Hz sampling rate), so you should avoid using a model order higher than half the samples available in the epoch.&lt;br /&gt;
When you are finished, remember to confirm your choices by slecting DONE. &lt;br /&gt;
&lt;br /&gt;
In addition, a button in the Spectral Extimation frame allows you to revert to the original values. &lt;br /&gt;
&lt;br /&gt;
Altogether you have to specify:&lt;br /&gt;
&lt;br /&gt;
:* which data (in each trial) you want to take into account. Mu will only use the part of the trial when the cursor is visible, while MuExtended will take into account all the period when the target is visible. To learn more, see section D2Box Application States &lt;br /&gt;
:* If you have made an artifact rejection (or noted on the run sheet during the acquisition which trials contain artifacts), you can instruct the software not to use them&lt;br /&gt;
:* Finally, you must decide how the software must extract EEG epochs from the continuous data&lt;br /&gt;
The epochs can be partially overlapped. This attenuates the data loss in case the length of a trial is not a multiple of the length of an epoch.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The percentage of overlap can be set both in Mario GUI and in any batch script. It is equal to the value of the &#039;&#039;MU_params.overlapping&#039;&#039; variable and the corresponding GUI field can be found by clickiing on &#039;&#039;Set Analysis Details&#039;&#039; on MARIO main form.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
At this point you can start the analysis by clicking on the Evaluate and Plot button.&lt;br /&gt;
&lt;br /&gt;
[[Image:Mu Rhy8.jpg]]&lt;br /&gt;
&lt;br /&gt;
== View results ==&lt;br /&gt;
&lt;br /&gt;
The first figure that appears is the R-square matrix (channels x frequency bins)&lt;br /&gt;
=== R-square matrix ===&lt;br /&gt;
&lt;br /&gt;
The r-square matrix highlights the most relevant spectral features for the separation of the two classes of EEG - Cursor Up (target 1) and Cursor Down (target 2).&lt;br /&gt;
&lt;br /&gt;
[[Image:Mu Rhy8.jpg]]&lt;br /&gt;
&lt;br /&gt;
Each row of the matrix is related to a single channel, while a column represents a frequency bin (labeled with its central frequency). The color codes the statistical significance of the difference between the two kinds of evoked potentials.&lt;br /&gt;
&lt;br /&gt;
Thus a red color would mean that, on that channel and for that frequency, the &amp;quot;Up&amp;quot; EEG is significantly synchronized with respect to &amp;quot;Down&amp;quot; EEG.&lt;br /&gt;
&lt;br /&gt;
Clicking on a cell of the matrix will open two more windows:&lt;br /&gt;
&lt;br /&gt;
* Power spectral distribution of the selected channel&lt;br /&gt;
* Topographic maps at the selected frequency.&lt;br /&gt;
&lt;br /&gt;
You can choose whether to overwrite or to put the most recently evoked figures beside the previous one. Two sets of waveform/topography figures are available, and are linked to the click of the left, the central or right mouse button.&lt;br /&gt;
&amp;lt;b&amp;gt;Left Button&amp;lt;/b&amp;gt; will create/overwrite a first figure, &amp;lt;b&amp;gt;Right Button&amp;lt;/b&amp;gt; will do the same on a second figure, the &amp;lt;b&amp;gt;Central Button&amp;lt;/b&amp;gt; will always open a new plot.&lt;br /&gt;
&lt;br /&gt;
=== Power Spectra and Topographic Plots ===&lt;br /&gt;
&lt;br /&gt;
In the lower panel you can find the spectral density of power for both classes of EEG. The Blue line refers to the &amp;quot;Up&amp;quot; condition, while the Red line refers to the &amp;quot;Down&amp;quot; condition.&lt;br /&gt;
We can see that at the vertex the &amp;quot;Down&amp;quot; condition is generally more synchronized than the &amp;quot;Up&amp;quot;, with maximal difference in the beta band, consistently with what is shown by the R-square matrix.  The proportinality between spectral differences and R-square is anyway rough, since r-square is sensitive to the dispersion (variance) of single trials; thus, small differences between spectra could bring to a high r-square, if they were very reproducible.&lt;br /&gt;
&lt;br /&gt;
The peak around 50 Hz is due to mains disturbance; this also allows you to appreciate the leakage introduced by the spectral estimation.&lt;br /&gt;
&lt;br /&gt;
[[Image:Mu_Rhy9.jpg]]&lt;br /&gt;
&lt;br /&gt;
Over the spectral graph, a topographic plot shows the scalp distribution of the r-square.&lt;br /&gt;
&lt;br /&gt;
The color coding is the same as the r-square matrix figure, and values on each channel are interpolated to create a continuous bidimensional map. The higher the number of electrodes, the more accurate is the map. With Surface Laplacian spatial filtering, the number of channels shown on the scalp may not coincide with the whole number of electrodes, since the value of the laplacian is not computed on the border channels.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The first step in the preliminary analysis of P300 BCI data is to find the absolute maximum of r-square. This simple statement must be mediated with a proper knowledge of physiological phenomena. In fact, we do not expect any sensorimotor activity at 3 Hz, so if the absolute maximum is at that frequency, you must suspect that it is actually an artifact. The same holds true if the spatial localization of the peak is far away from the centro-parietal electrodes.&lt;br /&gt;
&lt;br /&gt;
From a practical point of view, it is not important, now, to understand the reasons different component that explain the desynchrinization peak on Cz at 17 Hz, as far as we are confident that this component is stable enough to be exploitable during the next session to control the cursor.&lt;br /&gt;
&lt;br /&gt;
The absolute value of R-square is mathematically bound to lie in the interval between 0 and 1. Values above 0.4 allow a rate of missed target on the order of a few percent. Values around 0.1 are promising. Values below 0.03 are possibly due to random fluctuations. All the previous figures are referred to analyses made on 240 trials.&lt;br /&gt;
&#039;&#039;&amp;lt;b&amp;gt;Beware of artifacts!&amp;lt;/b&amp;gt;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
During the acquisition, you should be particularly careful to avoid artifacts. While EOG and blink artifacts are confined to very low frequencies, EMG artifacts are mostly on the beta band and could largely overlap with the frequency band that characterizes the mu rhythm.&lt;br /&gt;
&lt;br /&gt;
If contaminated data was acquired, then you have two problems:&lt;br /&gt;
&lt;br /&gt;
:* Realize that EMG is superimposed on the to data&lt;br /&gt;
:* Distinguish between spectral modulation introduced by EEG and by EMG &lt;br /&gt;
&lt;br /&gt;
The first task is not as trivial as it might appear. If you did not acquire the data yourself (or even if you did) you might complete the analysis procedure without giving a single glance to the raw data. So you must be particularly careful when you analyze the R-square maps, and always check if the peak you are seeing might be due to an artifact.&lt;br /&gt;
&lt;br /&gt;
Discriminant features between EEG and EMG are both in the frequency distribution and in the spatial distribution.&lt;br /&gt;
&lt;br /&gt;
EMG that strongly affects the recordings is mostly generated by muscles at the forehead or close to the ears/jaws. Thus, their spatial distribution is such that the most responsive channel is one of those at the border of the montage. Of course, due to volume conduction, the effects can be seen even on electrodes on the opposite part of the montage, but they show a degrading pattern.&lt;br /&gt;
On the other hand, a peak that shows its maximum on a central channel, can hardly be generated by a muscle or by other non-cephalic source.&lt;br /&gt;
&lt;br /&gt;
The spectrum of EEG is mainly concentrated in the alpha band, with a possible flatter and lower peak in beta. With the exception of the beta peak/plateau, the EEG spectrum decreases almost linearly (if measured in dB) after 12 Hz.&lt;br /&gt;
On the other hand, the EMG spectrum becomes significant at about 20 Hz and is still very high at the highest frequencies we usually analyze (60 Hz). A spectrum with a pattern more similar to the latter, may indicate that non-EEG activity is present in the data.&lt;br /&gt;
&lt;br /&gt;
==Improving the analysis==&lt;br /&gt;
&lt;br /&gt;
The first cause of an unsuccessful analysis is  poor quality of the recording. For this reason it is highly recommended that, at least for the first experiments, the subject be highly motivated and cooperative. If this is the case, data of low quality are usually present in one or a few runs. And if the experimenter is careful enough, he/she should have noted the occurrence of strong artifacts on the run sheet.&lt;br /&gt;
In this case, the next step is to repeat an unsatisfactory data analysis after having excluded the (putative) bad runs.&lt;br /&gt;
To do this, just go back to the file selection dialog, choose LOAD Data again and load only the runs that you believe are clean. The number of runs should not be too low (as a rule of thumb, the data set should contain at least 100 trials), otherwise the r-square statistical analysis would loose sensitivity.&lt;br /&gt;
&lt;br /&gt;
== Analyzing the Screening ==&lt;br /&gt;
&lt;br /&gt;
The screening experiment is not different from a regular training session, from the point of view of data format. You will have four sets (horizontal movement, horizontal imagination, vertical movement, and vertical imagination) of three runs, containing EEG acquired in two conditions (up and down, or left and right).&lt;br /&gt;
&lt;br /&gt;
Start analyzing the vertical movement execution, and mark a few possible responsive features. The analysis on the vertical movement imagination should confirm (though with a lower R-square) those that are actually related to sensorimotor cognitive states.&lt;br /&gt;
&lt;br /&gt;
In the case that no reliable responsive EEG feature is found, the analysis can be repeated on the horizontal dataset.&lt;br /&gt;
&lt;br /&gt;
If both the vertical and horizontal dataset show responsive features, and these are different, the subject should be trained for some session on the vertical training until he/she decreases the false positive below 10%; at that point, the training of the horizontal modulation can begin, with the aim that, at a certain point, the subject can control both the vertical and the horizontal simultaneously in a two-dimensional task.&lt;br /&gt;
&lt;br /&gt;
==Conclusions==&lt;br /&gt;
&lt;br /&gt;
If you are confident that you have found a significant difference between conditions that is due to EEG rather than an artifact, and that reflects a cognitive process that is likely to be reproduced (or even enhanced with training) in the next session, you have reached your goal.&lt;br /&gt;
The next time the same subject practices with the D2Box Application, you will have to change the MUD matrix so that it reflects the feature that you just outlined.&lt;br /&gt;
&lt;br /&gt;
==Troubleshooting==&lt;br /&gt;
&lt;br /&gt;
Some OpenGL drivers may sometimes show defective figures like the following:&lt;br /&gt;
&lt;br /&gt;
[[Image:Defective.jpg]]&lt;br /&gt;
&lt;br /&gt;
Matlab customers can get around this problem using this simple procedure:&lt;br /&gt;
:* Select the defective figure window&lt;br /&gt;
:* Go to the Matlab Command Window&lt;br /&gt;
:* Execute one of the following command line:&lt;br /&gt;
:**set(gcf, &#039;Renderer&#039;, &#039;Painters&#039;);&lt;br /&gt;
:**set(gcf, &#039;Renderer&#039;, &#039;zbuffer&#039;)&lt;br /&gt;
&lt;br /&gt;
The figure will be a plot using a different renderer (Painters or zBuffer).&lt;/div&gt;</summary>
		<author><name>Atennissen</name></author>
	</entry>
	<entry>
		<id>https://www.bci2000.org/mediawiki/index.php?title=Programming_Reference:Debug_Output&amp;diff=1775</id>
		<title>Programming Reference:Debug Output</title>
		<link rel="alternate" type="text/html" href="https://www.bci2000.org/mediawiki/index.php?title=Programming_Reference:Debug_Output&amp;diff=1775"/>
		<updated>2007-05-09T17:28:45Z</updated>

		<summary type="html">&lt;p&gt;Atennissen: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;When writing your own BCI2000 module, you will sometimes want to report values of variables, execution of a certain function, or other information that is &lt;br /&gt;
*irrelevant to the user, but&lt;br /&gt;
*helps you check whether your code does what it is supposed to.&lt;br /&gt;
&lt;br /&gt;
Often, programmers use individual log files for debugging output, and review those files while their program runs, or afterwards.&lt;br /&gt;
&lt;br /&gt;
This page describes how the BCI2000 C++ framework allows you to easily display debugging information in the operator module&#039;s log window, without bothering about creating your own log file.&lt;br /&gt;
Nevertheless, you are free to use your own log file if you feel that this better fits your needs.&lt;br /&gt;
&lt;br /&gt;
==Debugging Stream &amp;lt;tt&amp;gt;bcidbg&amp;lt;/tt&amp;gt;==&lt;br /&gt;
Similar to the &amp;lt;tt&amp;gt;bcierr&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;bciout&amp;lt;/tt&amp;gt; streams used for error handling and user warnings, BCI2000 provides a &amp;lt;tt&amp;gt;std::ostream&amp;lt;/tt&amp;gt; derived object that accepts strings and numbers for formatted output.&lt;br /&gt;
Like the output of &amp;lt;tt&amp;gt;bcierr&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;bciout&amp;lt;/tt&amp;gt;, data from &amp;lt;tt&amp;gt;bcidbg&amp;lt;/tt&amp;gt; is directed into the operator module&#039;s log window.&lt;br /&gt;
Similar to error and warning messages, debugging messages will be time stamped and provided with a function context.&lt;br /&gt;
&lt;br /&gt;
However, there are important differences:&lt;br /&gt;
*Unlike for &amp;lt;tt&amp;gt;bcierr&amp;lt;/tt&amp;gt;, the framework does not interpret the fact that something was written to the stream.&lt;br /&gt;
*&amp;lt;tt&amp;gt;bcidbg&amp;lt;/tt&amp;gt; can conditionally &#039;&#039;&#039;ignore&#039;&#039;&#039; the data inserted into it, according to a user-defined global setting. That way, you need not remove your debugging code, nor devise your own conditional output scheme.&lt;br /&gt;
*Messages are formatted unobtrusively, and will not automatically pop up the window.&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;tt&amp;gt;bcidbg&amp;lt;/tt&amp;gt; stream is available globally, and used as any other &amp;lt;tt&amp;gt;std::ostream&amp;lt;/tt&amp;gt; descendant:&lt;br /&gt;
 mSomeDataMember = SomeFunction();&lt;br /&gt;
 bcidbg &amp;lt;&amp;lt; &amp;quot;Set mSomeDataMember to &amp;quot; &amp;lt;&amp;lt; mSomeDataMember &amp;lt;&amp;lt; endl;&lt;br /&gt;
&lt;br /&gt;
Note that, just as for &amp;lt;tt&amp;gt;bcierr&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;bciout&amp;lt;/tt&amp;gt;, writing to &amp;lt;tt&amp;gt;bcidbg&amp;lt;/tt&amp;gt; will not take effect unless it is flushed by inserting &amp;lt;tt&amp;gt;flush&amp;lt;/tt&amp;gt; or &amp;lt;tt&amp;gt;endl&amp;lt;/tt&amp;gt;. (The latter will insert a newline character before flushing the stream.)&lt;br /&gt;
&lt;br /&gt;
==The Debug Level==&lt;br /&gt;
A &#039;&#039;Debug Level&#039;&#039; concept is used to control the output of debug messages.&lt;br /&gt;
Basically, a user-specified debug level is compared to the debug levels of individual messages,  and messages with a debug level &#039;&#039;above&#039;&#039; the user-specified debug level will be &#039;&#039;suppressed&#039;&#039; from the output. As the debug level defaults to 0, no debug messages will be visible to an end user unless configured accordingly.&lt;br /&gt;
&lt;br /&gt;
Individual messages are associated with a numerical value, their &#039;&#039;Debug Level&#039;&#039;, roughly correlating with their significance. Important and sparse messages are given a low debug level value, less important and probably more frequent messages are given a higher debug level.&lt;br /&gt;
&lt;br /&gt;
===Message Debug Level===&lt;br /&gt;
The default message debug level is 1.&lt;br /&gt;
 bcidbg &amp;lt;&amp;lt; &amp;quot;This is an important message on any level of debugging&amp;quot; &amp;lt;&amp;lt; endl;&lt;br /&gt;
To give a message a higher debug level, put it in brackets after the &amp;lt;tt&amp;gt;bcidbg&amp;lt;/tt&amp;gt; name:&lt;br /&gt;
 bcidbg( 10 ) &amp;lt;&amp;lt; &amp;quot;This is a fairly uninteresting message&amp;quot; &amp;lt;&amp;lt; endl;&lt;br /&gt;
Although there is practically no upper limit to debug level values, &lt;br /&gt;
a usual range for debug levels is from 1 to 10.&lt;br /&gt;
&lt;br /&gt;
===Global Debug Level===&lt;br /&gt;
The amount of actual debugging output is governed by a global debug level.&lt;br /&gt;
In BCI2000, this value is corresponds to the &#039;&#039;&#039;DebugLevel&#039;&#039;&#039; parameter. This parameter is not normally available, and must be specified from the command line when starting a module:&lt;br /&gt;
 FeedbackDemo 127.0.0.1 --DebugLevel=10&lt;br /&gt;
will start the FeedbackDemo module with a debug level of 10.&lt;br /&gt;
Note that the debug level parameter will propagate to the other modules only after &amp;quot;Set Config&amp;quot; has been pressed from the operator module. Thus, other modules must be started with the DebugLevel argument, as well, if you need to view debugging messages from operation phases prior to the Initialization Phase.&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
See also: [[Error Streams]]|[[States of Operation]]&lt;/div&gt;</summary>
		<author><name>Atennissen</name></author>
	</entry>
	<entry>
		<id>https://www.bci2000.org/mediawiki/index.php?title=Programming_Howto:Using_TortoiseSVN&amp;diff=1774</id>
		<title>Programming Howto:Using TortoiseSVN</title>
		<link rel="alternate" type="text/html" href="https://www.bci2000.org/mediawiki/index.php?title=Programming_Howto:Using_TortoiseSVN&amp;diff=1774"/>
		<updated>2007-05-09T16:47:52Z</updated>

		<summary type="html">&lt;p&gt;Atennissen: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Using TortoiseSVN for Day-to-Day Tasks ==&lt;br /&gt;
&lt;br /&gt;
=== Updating to the latest version of the BCI2000 project ===&lt;br /&gt;
Once you set up client access as described on the [[SVN Client Setup]] page, &lt;br /&gt;
there will be&lt;br /&gt;
a folder on your harddisk, probably named &amp;quot;BCI2000&amp;quot;, and initially displayed with a&lt;br /&gt;
green overlay icon. The green overlay icon indicates that all files below the&lt;br /&gt;
folder are unchanged since they were checked out.&lt;br /&gt;
To bring an existing BCI2000 source tree up to date, right-click the folder&lt;br /&gt;
named &amp;quot;BCI2000&amp;quot;, and choose &amp;quot;SVN Update&amp;quot; from the context menu. If you&lt;br /&gt;
edited a file, and did not commit your changes, a SVN update operation will&lt;br /&gt;
merge possible changes made to the server version into your file (but keeping&lt;br /&gt;
your original version as a backup with a different name). If you prefer,&lt;br /&gt;
you might consider doing a &amp;quot;commit&amp;quot; prior to an &amp;quot;update&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Note: &#039;&#039;&#039;There is no indication&#039;&#039;&#039; that someone changed a file on the&lt;br /&gt;
server since you downloaded it!&lt;br /&gt;
Changes on the server will be unknown to&lt;br /&gt;
your local SVN files unless you perform an &amp;quot;SVN update&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Committing (i.e., writing back) changes you made ===&lt;br /&gt;
If you edit a file on your local hard disk which is under SVN, TortoiseSVN&lt;br /&gt;
will display it with a red overlay icon. This indicates that the file&#039;s content&lt;br /&gt;
differs from the file as it was when you downloaded it from the&lt;br /&gt;
SVN server. &lt;br /&gt;
&lt;br /&gt;
Once you consider your changes permanent, it is time to write the file&lt;br /&gt;
back to the server. This process is called &amp;quot;committing changes&amp;quot; – to perform&lt;br /&gt;
it on all files below a certain folder, right-click that folder, and choose &amp;quot;SVN&lt;br /&gt;
Commit...&amp;quot;. You will be presented a list of files below that folder from&lt;br /&gt;
which you may exclude certain ones, or display a list of differences (&amp;quot;Compare with base&amp;quot;) &lt;br /&gt;
to the version on the SVN server. &lt;br /&gt;
If you try to commit changes of files for which you don’t have write access, you will be prompted for a different user name and password repeatedly.&lt;br /&gt;
Please contact an [[administrator]] if you think there is a problem with user rights.&lt;br /&gt;
&lt;br /&gt;
=== Adding new files ===&lt;br /&gt;
If there are new files inside your BCI2000 folder which TortoiseCVS does not&lt;br /&gt;
know about, they will be displayed without an overlay icon. Those&lt;br /&gt;
files or folders may be added to the BCI2000 source tree on the server by&lt;br /&gt;
choosing &amp;quot;TortoiseSVN-&amp;gt;Add...&amp;quot; from the context menu that appears after right-clicking the respective file or folder.&lt;br /&gt;
Added files will be considered as empty on the server, and displayed with a&lt;br /&gt;
red overlay icon, until you perform a &amp;quot;SVN Commit&amp;quot; on them. You will&lt;br /&gt;
need write access to the respective area of the source tree in order to add&lt;br /&gt;
files and folders.&lt;br /&gt;
&lt;br /&gt;
== Comparison with other Versioning Software ==&lt;br /&gt;
&lt;br /&gt;
=== TortoiseSVN vs. MS VisualSourceSafe ===&lt;br /&gt;
Although the SVN Server/TortoiseSVN combination serves the same purpose as MS&lt;br /&gt;
VisualSourceSafe, there are two major differences that affect you as a user:&lt;br /&gt;
* With TortoiseSVN, you directly operate on files that are &#039;&#039;&#039;located on your own hard disk&#039;&#039;&#039;, and you do so from a true Windows Explorer window, right clicking onto a file or folder and choosing the appropriate SVN operation from the context menu. With MS VisualSourceSafe, you use a Windows Explorer-like program window to operate on files located inside a database on a server.&lt;br /&gt;
* With MS VisualSourceSafe, files that were checked-out for editing were &#039;&#039;&#039;blocked for changes&#039;&#039;&#039; as far as other users were concerned. With SVN, there is no exclusive checking out of files. Instead, changes made by different users will be merged into to a combined version – otherwise, contradicting changes must be resolved manually (which is a quite rare condition in practice).&lt;br /&gt;
&lt;br /&gt;
=== SVN vs. CVS ===&lt;br /&gt;
SVN and CVS both follow a similar philosophy of non-exclusive editing of files, and a similar terminology. Thus, differences are minor (for a concise discussion, see http://www.pushok.com/soft_svn_vscvs.php).&lt;br /&gt;
Especially when switching from TortoiseCVS to TortoiseSVN, you will hardly notice any difference when it comes to everyday tasks.&lt;br /&gt;
&lt;br /&gt;
==See also==&lt;br /&gt;
*[[SVN Client Setup]]&lt;br /&gt;
&lt;br /&gt;
[[Category:Howto]] [[Category:Development]] [[Category:Preliminaries]]&lt;/div&gt;</summary>
		<author><name>Atennissen</name></author>
	</entry>
	<entry>
		<id>https://www.bci2000.org/mediawiki/index.php?title=User_Reference:Normalizer&amp;diff=1772</id>
		<title>User Reference:Normalizer</title>
		<link rel="alternate" type="text/html" href="https://www.bci2000.org/mediawiki/index.php?title=User_Reference:Normalizer&amp;diff=1772"/>
		<updated>2007-05-09T16:39:57Z</updated>

		<summary type="html">&lt;p&gt;Atennissen: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Function==&lt;br /&gt;
===Normalizing Transform===&lt;br /&gt;
The Normalizer applies a linear transformation to its input signal.&lt;br /&gt;
For each channel (index denoted with &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;, an offset value is subtracted, and the result multiplied with a gain value:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\textrm{output}_i=(\textrm{input}_i-\textrm{NormalizerOffset}_i)\times \textrm{NormalizerGain}_i&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Adaptation===&lt;br /&gt;
From the past statistics of its input, the Normalizer estimates offset and gain values adaptively to make its output signal&lt;br /&gt;
*zero mean, and&lt;br /&gt;
*unit variance.&lt;br /&gt;
The Normalizer uses &#039;&#039;data buffers&#039;&#039; to accumulate its past input according to user-defined rules.&lt;br /&gt;
These rules are called &#039;&#039;buffer conditions&#039;&#039; because they are given in terms of boolean expressions.&lt;br /&gt;
Each data buffer is associated with such a boolean expression. Whenever an expression evaluates to &#039;&#039;true&#039;&#039;, the current input will be appended to the associated buffer.&lt;br /&gt;
Whenever it comes to updating offset and gain values, the Normalizer will use the content of its buffers to estimate data mean and variance. The offset will then be set to the data mean, and the gain to the inverse square root of the data variance, i.e., the inverse of the data standard deviation.&lt;br /&gt;
&lt;br /&gt;
===Adaptation Rationale===&lt;br /&gt;
It may appear crude to use the total data variance for the adaptation -- why not use linear regression on data labels (target codes) to separate into user controlled (task determined) and noise variance? User controlled variance would then correspond to target separation on the feedback screen, which is what we want to normalize in the first place.&lt;br /&gt;
&lt;br /&gt;
However, a closer look reveals that the &#039;&#039;relative size&#039;&#039; of user controlled variance, and noise variance is crucial. When that &amp;quot;signal&amp;quot; variance is small compared to noise variance, we would be ill advised to use it in normalization -- this would only lead to enlarged noise, and an erratically moving cursor on the feedback screen.&lt;br /&gt;
In this case, we rather want to normalize by noise variance, to keep the cursor well-behaved. At the same time, total variance approaches noise variance in this limit because signal variance is small.&lt;br /&gt;
&lt;br /&gt;
On the other end of the spectrum, we have a signal variance that is large compared to noise variance. Here, we clearly want normalization by signal variance. However, the total variance will be dominated by signal variance. Thus, in the limit of high signal-to-noise ratio, total variance again is the entity by which we want to normalize.&lt;br /&gt;
&lt;br /&gt;
Thus, no matter whether signal-to-noise ratio is high or low, total data variance is a good choice for normalization.&lt;br /&gt;
&lt;br /&gt;
===Typical Use===&lt;br /&gt;
Typically, the Normalizer&#039;s input is the output of a classifier, which it transforms into a zero mean/unit variance control signal which is then transmitted to an application module.&lt;br /&gt;
Using the zero mean/unit variance property, an application module can then relate entities such as window size, screen update rate, cursor speed, and trial duration.&lt;br /&gt;
&lt;br /&gt;
==Parameters==&lt;br /&gt;
For each channel of the Normalizer&#039;s input signal, adaptation is treated independently.&lt;br /&gt;
Offsets, Gains, and Adaptation kind are represented as list parameters, with each entry in the list corresponding to a signal channel.&lt;br /&gt;
Buffer configuration is done in matrix form, with columns corresponding to signal channels, and rows corresponding to multiple buffers.&lt;br /&gt;
&lt;br /&gt;
===NormalizerOffsets, NormalizerGains=== &lt;br /&gt;
Lists of offset and gain values, with entries corresponding to signal channels. These values will be updated depending on the channel&#039;s adaptation configuration in the Adaptation parameter.&lt;br /&gt;
===Adaptation===&lt;br /&gt;
A list of values that determines the adaptation strategy of an individual channel. Possible values are&lt;br /&gt;
*0 for no adaptation,&lt;br /&gt;
*1 for adjusting offsets to zero mean,&lt;br /&gt;
*2 for additionally adjusting gains to unit variance.&lt;br /&gt;
===BufferConditions===&lt;br /&gt;
A matrix consisting of [[User Reference:Expression Syntax|boolean expressions]].&lt;br /&gt;
Expressions may involve [[States]] and the components of the Normalizer&#039;s input signal.&lt;br /&gt;
*Each matrix entry represents a data buffer which is a ring buffer of length &#039;&#039;BufferLength.&#039;&#039; Whenever a buffer&#039;s expression evaluates to &#039;&#039;true,&#039;&#039; the current value of the input signal will be put into the buffer (overwriting past data once the buffer is filled).&lt;br /&gt;
*Buffers in a certain column will buffer data from the corresponding signal channel, and will be used in adaptation of that channel only.&lt;br /&gt;
*Within columns, the order of buffers does not affect computation.&lt;br /&gt;
*Empty expressions do not have any effect on the computation. Thus, it is possible to have a different number of buffers for different channels.&lt;br /&gt;
*A buffer to store data for the first target, and during feedback only, should have an expression such as &amp;lt;code&amp;gt;(Feedback)&amp;amp;&amp;amp;(TargetCode==1)&amp;lt;/code&amp;gt;.&lt;br /&gt;
===BufferLength===&lt;br /&gt;
The maximum length of each data buffer.&lt;br /&gt;
*The length is specified in data blocks if given as a raw number, and in seconds if given as a number followed by the character &amp;quot;s&amp;quot;.&lt;br /&gt;
*All data buffers have the same capacity.&lt;br /&gt;
*Once a data buffer is filled, its older entries will be replaced with new data (ring buffer).&lt;br /&gt;
*In previous versions of BCI2000, buffer lengths were specified in terms of &amp;quot;past trials&amp;quot;. However, this would enforce the notion of a &amp;quot;trial&amp;quot;, and not generalize to continuous adaptation.&lt;br /&gt;
===UpdateTrigger===&lt;br /&gt;
A [[User Reference:Expression Syntax|boolean expression]] that triggers adaptation when changing to &#039;&#039;true&#039;&#039; from &#039;&#039;false&#039;&#039;.&lt;br /&gt;
Generally, continuous adaptation within trials is not desired. Rather, one wants adaptation to occur at the end of a trial. This is achieved with &#039;&#039;UpdateTrigger&#039;&#039; expressions such as &amp;lt;code&amp;gt;Feedback!=0&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;TargetCode!=0&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==States==&lt;br /&gt;
Buffer condition expressions, and the UpdateTrigger expression may involve any [[State]] present in the system. Expressions are checked for syntactical correctness and whether states are present during the [[Preflight Phase]].&lt;br /&gt;
&lt;br /&gt;
==Examples==&lt;br /&gt;
===Trial-based 1D Feedback Task with 3 Targets===&lt;br /&gt;
*Only data from the feedback phase should enter into the adaptation.&lt;br /&gt;
*To make sure that targets contribute equally to the adaptation, we use a single buffer for each target. &amp;lt;p /&amp;gt;We use a 3-rows-by-1-column BufferConditions matrix:&lt;br /&gt;
 (Feedback)&amp;amp;&amp;amp;(TargetCode==1)&lt;br /&gt;
 (Feedback)&amp;amp;&amp;amp;(TargetCode==2)&lt;br /&gt;
 (Feedback)&amp;amp;&amp;amp;(TargetCode==3)&lt;br /&gt;
*We want to use data from three previous trials of each target. &lt;br /&gt;
*Feedback duration is 2 seconds.&amp;lt;p /&amp;gt;We set the buffer length to the equivalent of three feedback durations:&lt;br /&gt;
  BufferLength= 6s&lt;br /&gt;
*Adaptation should happen at the end of each trial, when feedback is finished.&amp;lt;p /&amp;gt;We set UpdateTrigger to an expression that changes to &#039;&#039;true&#039;&#039; when feedback ends:&lt;br /&gt;
  UpdateTrigger= (Feedback==0)&lt;br /&gt;
&lt;br /&gt;
===Trial-based 2D Feedback Task with 4 Targets===&lt;br /&gt;
*Leaving everything else as in the previous example, we now have two dimensions corresponding to left-right (channel 1) and up-down (channel 2).&lt;br /&gt;
:Target positions are as indicated below:&lt;br /&gt;
  ---------------------------&lt;br /&gt;
  |          ##1##          |&lt;br /&gt;
  |#                       #|&lt;br /&gt;
  |2                       3|&lt;br /&gt;
  |#                       #|&lt;br /&gt;
  |          ##4##          |&lt;br /&gt;
  ---------------------------&lt;br /&gt;
:We use data from targets 1 and 4 to adjust channel 2, and targets 2 and 3 to adjust channel 1. Accordingly, the BufferConditions matrix is&lt;br /&gt;
 (Feedback)&amp;amp;&amp;amp;(TargetCode==2) (Feedback)&amp;amp;&amp;amp;(TargetCode==1)&lt;br /&gt;
 (Feedback)&amp;amp;&amp;amp;(TargetCode==3) (Feedback)&amp;amp;&amp;amp;(TargetCode==4)&lt;br /&gt;
&lt;br /&gt;
===Continuous 1D Control without pre-defined Targets===&lt;br /&gt;
*We know that, over a period of 10 minutes, all output values will occur with approximately equal frequency, or at least have a symmetric distribution around zero. This matches the combination of BCI2000 and Dasher or other &amp;quot;devices&amp;quot; expecting statistically balanced input.&lt;br /&gt;
:The BufferConditions matrix will have a single entry containing a constant expression:&lt;br /&gt;
 1&lt;br /&gt;
:This way, data will always be buffered.&lt;br /&gt;
*There are no trials. We want a continuous adaptation to the values of the last 10 minutes.&lt;br /&gt;
:We set the BufferLength parameter to &amp;lt;code&amp;gt;600s&amp;lt;/code&amp;gt;, or &amp;lt;code&amp;gt;(10*60)s&amp;lt;/code&amp;gt;.&lt;br /&gt;
:For continuous adaptation, we enter an &#039;&#039;empty string&#039;&#039; (not a constant 0 expression) for UpdateTrigger.&lt;br /&gt;
----&lt;br /&gt;
See also: [[User Reference:Expression Syntax]]&lt;/div&gt;</summary>
		<author><name>Atennissen</name></author>
	</entry>
	<entry>
		<id>https://www.bci2000.org/mediawiki/index.php?title=Technical_Reference:System_Design&amp;diff=1771</id>
		<title>Technical Reference:System Design</title>
		<link rel="alternate" type="text/html" href="https://www.bci2000.org/mediawiki/index.php?title=Technical_Reference:System_Design&amp;diff=1771"/>
		<updated>2007-05-09T16:30:28Z</updated>

		<summary type="html">&lt;p&gt;Atennissen: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Overview==&lt;br /&gt;
While BCIs can differ widely in the nature of the physiological components they &lt;br /&gt;
use, the signal processing they perform, the feedback they provide, or  &lt;br /&gt;
the underlying training and operation paradigm, they all need the same four &lt;br /&gt;
elements: EEG data collection, signal processing, an output device and manual or &lt;br /&gt;
automatic parameterization and configuration. Therefore, it seems to be a &lt;br /&gt;
natural choice to partition the system into four modules with respect to  &lt;br /&gt;
functionality. &lt;br /&gt;
It is conceivable that for certain BCIs, the chosen decomposition might be &lt;br /&gt;
overkill, or even unfavorable, but still these modules seem to be the most appropriate &lt;br /&gt;
for a variety of systems.&lt;br /&gt;
&lt;br /&gt;
In accordance with this decomposition, BCI2000 consists of four modules that communicate with each other. (See Figure 1.) These modules are called &#039;&#039;Source&#039;&#039;, &#039;&#039;Signal Processing&#039;&#039;, &#039;&#039;Application&#039;&#039;, and &#039;&#039;Operator&#039;&#039;. We will&lt;br /&gt;
refer to the three modules Source, Signal Processing and Application&lt;br /&gt;
together as&lt;br /&gt;
&#039;&#039;core modules&#039;&#039;.&lt;br /&gt;
[[Image:BCI2000 SysDes_Modules.png|center|thumb|300px|Fig. 1 The functional modules and their interfaces]]&lt;br /&gt;
&lt;br /&gt;
In a binary distribution, the four modules correspond to executables.&lt;br /&gt;
For modules other than the operator module, executable file names vary, reflecting specializations of the generic modules.&lt;br /&gt;
&lt;br /&gt;
{|border=&amp;quot;1&amp;quot;&lt;br /&gt;
|+ Example Configuration&lt;br /&gt;
! Module Name !! Executable File Name !! Notes&lt;br /&gt;
|-&lt;br /&gt;
| Operator || Operat.exe || &amp;amp;nbsp;&lt;br /&gt;
|- &lt;br /&gt;
| EEG source || gUSBamp.exe || data acquisition from the gUSBamp g.tec amplifier&lt;br /&gt;
|-&lt;br /&gt;
| Signal Processing || ARSignalProcessing.exe || auto-regressive spectral estimation&lt;br /&gt;
|-&lt;br /&gt;
| Application || CursorTask.exe || moving a cursor by brain activity&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==Core-Operator Communication==&lt;br /&gt;
===Introduction===&lt;br /&gt;
The same communication protocol is used between each of the three core&lt;br /&gt;
modules&lt;br /&gt;
and the operator module. Although it can be implemented on top of any&lt;br /&gt;
transport&lt;br /&gt;
protocol, the communication protocol assumes the reliability of TCP (i.e., the protocol does&lt;br /&gt;
not support&lt;br /&gt;
acknowledgements or packet sorting or any other means of error&lt;br /&gt;
correction).&lt;br /&gt;
Communication consists of [[BCI2000 messages|messages]] that are sent and received&lt;br /&gt;
asynchronously&lt;br /&gt;
between any core module and the operator module. &lt;br /&gt;
Below, an overview of message types is given. For details about specific messages, refer to the [[BCI2000 messages]] page.&lt;br /&gt;
&lt;br /&gt;
===Status Information Messages===&lt;br /&gt;
[[Type:Status|Status]] messages are used to communicate errors and to convey status&lt;br /&gt;
information (e.g., the operator module may display the remaining disc space on the Source&lt;br /&gt;
module&#039;s machine).&lt;br /&gt;
&lt;br /&gt;
===Parameter Messages===&lt;br /&gt;
These messages transport [[Type:Parameter|Parameters]] carrying configuration information.&lt;br /&gt;
The operator module receives parameter messages from core modules, which enable it to display parameters in a configuration dialog, and to save parameters to, and load them from a [[parameter file]].&lt;br /&gt;
&lt;br /&gt;
===State Messages===&lt;br /&gt;
The core modules and the operator module use messages containing [[Type:State|States]] to&lt;br /&gt;
communicate in the system initialization phase,&lt;br /&gt;
as well as during system performance and&lt;br /&gt;
for system termination.&lt;br /&gt;
&lt;br /&gt;
===Visualization Messages===&lt;br /&gt;
[[Type:Visualization|Visualization]] messages are sent from core modules to the operator module, which in turn displays their content to the operator user.&lt;br /&gt;
These messages may contain signal data for graphical display, or text to be displayed in a log window. &lt;br /&gt;
A core module may also configure details of the display sending configuration messages.&lt;br /&gt;
&lt;br /&gt;
===System Command Messages===&lt;br /&gt;
[[Type:System Command|System Commands]] are meta-messages used to control the behavior of individual modules by switching their internal state. Typical system commands are &amp;lt;tt&amp;gt;EndOfParameter&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;EndOfState&amp;lt;/tt&amp;gt;, to terminate a list of parameter or state messages.&lt;br /&gt;
The nature of these system commands is defined by the specific&lt;br /&gt;
implementation of&lt;br /&gt;
the modules.&lt;br /&gt;
&lt;br /&gt;
==Inter-Core Communication==&lt;br /&gt;
===Introduction===&lt;br /&gt;
Unlike the bidirectional communication between core modules and the&lt;br /&gt;
operator&lt;br /&gt;
module, communication within the core modules is unidirectional. The&lt;br /&gt;
initial&lt;br /&gt;
setup determines the exact nature of this communication and data is&lt;br /&gt;
transmitted&lt;br /&gt;
with the same protocol as described above. &lt;br /&gt;
&lt;br /&gt;
===State Vector Messages===&lt;br /&gt;
A [[Type:State Vector|State Vector]] is a data structure consisting of a series of &#039;&#039;StateVectorLength&#039;&#039; &lt;br /&gt;
subsequent bytes, representing an overall system state that is saved into a data file along with each block of data.&lt;br /&gt;
The state vector is always transmitted before the&lt;br /&gt;
brain&lt;br /&gt;
signal or control signal.&lt;br /&gt;
&lt;br /&gt;
===Brain Signal Messages===&lt;br /&gt;
From the source to the signal processing module, selected channels from the brain signal are transmitted as 32-bit floating point numbers calibrated into microvolts.&lt;br /&gt;
The brain signal format is similar to the data format used for graphic visualization messages.&lt;br /&gt;
&lt;br /&gt;
===Control Signal Messages===&lt;br /&gt;
From the signal processing to the application module, signal messages transfer decoded rather than raw brain signals. In both cases, the same kind of message is used.&lt;br /&gt;
Typically, control signals consist of two or three channels carrying signals with zero mean and unit variance.&lt;/div&gt;</summary>
		<author><name>Atennissen</name></author>
	</entry>
	<entry>
		<id>https://www.bci2000.org/mediawiki/index.php?title=Programming_Tutorial:Implementing_a_Source_Module&amp;diff=1770</id>
		<title>Programming Tutorial:Implementing a Source Module</title>
		<link rel="alternate" type="text/html" href="https://www.bci2000.org/mediawiki/index.php?title=Programming_Tutorial:Implementing_a_Source_Module&amp;diff=1770"/>
		<updated>2007-05-09T16:23:27Z</updated>

		<summary type="html">&lt;p&gt;Atennissen: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Data acquisition modules are factored into code required for any&lt;br /&gt;
hardware,&lt;br /&gt;
and code required to access a specific hardware.&lt;br /&gt;
You provide a function that waits for and reads A/D&lt;br /&gt;
data (line 3 in the EEG source pseudo code of [[Modules:Data Acquisition]]),&lt;br /&gt;
together with some helper functions that perform initialization and&lt;br /&gt;
cleanup tasks.&lt;br /&gt;
Together these functions form a class derived from&lt;br /&gt;
&amp;lt;tt&amp;gt;GenericADC&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==Scenario==&lt;br /&gt;
Your &#039;&#039;Tachyon Corporation&#039;&#039;  A/D card comes with a C-style&lt;br /&gt;
software interface&lt;br /&gt;
declared in a header file &amp;lt;tt&amp;gt;&amp;quot;TachyonLib.h&amp;quot;&amp;lt;/tt&amp;gt; that consists of&lt;br /&gt;
three&lt;br /&gt;
functions&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#define TACHYON_NO_ERROR 0&lt;br /&gt;
int TachyonStart( int inSamplingRate, int inNumberOfChannels );&lt;br /&gt;
int TachyonStop( void );&lt;br /&gt;
int TachyonWaitForData( short** outBuffer, int inCount );&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
From the library help file, you learn that &amp;lt;tt&amp;gt;TachyonStart&amp;lt;/tt&amp;gt;&lt;br /&gt;
configures the&lt;br /&gt;
card and starts acquisition to some internal buffer; that&lt;br /&gt;
&amp;lt;tt&amp;gt;TachyonStop&amp;lt;/tt&amp;gt;&lt;br /&gt;
stops acquisition to the buffer, and that &amp;lt;tt&amp;gt;TachyonWaitForData&amp;lt;/tt&amp;gt;&lt;br /&gt;
will block execution until the specified amount of data has been&lt;br /&gt;
acquired, and&lt;br /&gt;
that it will return a pointer to a buffer containing the data in its&lt;br /&gt;
first argument.&lt;br /&gt;
Each of the functions will return zero if everything went well, otherwise&lt;br /&gt;
some error value will be given.&lt;br /&gt;
Luckily, &#039;&#039;Tachyon Corporation&#039;&#039;  gives you just&lt;br /&gt;
what you need for a BCI2000 source module, so implementing the ADC&lt;br /&gt;
class is&lt;br /&gt;
quite straightforward.&lt;br /&gt;
&lt;br /&gt;
==Writing the ADC Header File==&lt;br /&gt;
In your class&#039; header file, &amp;lt;tt&amp;gt;&amp;quot;TachyonADC.h&amp;quot;&amp;lt;/tt&amp;gt;, you write&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#ifndef TACHYON_ADC_H&lt;br /&gt;
#define TACHYON_ADC_H&lt;br /&gt;
&lt;br /&gt;
#include &amp;quot;GenericADC.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
class TachyonADC : public GenericADC&lt;br /&gt;
{&lt;br /&gt;
 public:&lt;br /&gt;
   TachyonADC();&lt;br /&gt;
   ~TachyonADC();&lt;br /&gt;
&lt;br /&gt;
   void Preflight( const SignalProperties&amp;amp;, SignalProperties&amp;amp; ) const;&lt;br /&gt;
   void Initialize();&lt;br /&gt;
   void Process( const GenericSignal*, GenericSignal* );&lt;br /&gt;
   void Halt();&lt;br /&gt;
&lt;br /&gt;
 private:&lt;br /&gt;
   int  mSourceCh,&lt;br /&gt;
        mSampleBlockSize,&lt;br /&gt;
        mSamplingRate;&lt;br /&gt;
};&lt;br /&gt;
#endif // TACHYON_ADC_H&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==ADC Implementation==&lt;br /&gt;
In the .cpp file, you will need some &amp;lt;tt&amp;gt;#includes&amp;lt;/tt&amp;gt;, and a filter&lt;br /&gt;
registration:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;quot;TachyonADC.h&amp;quot;&lt;br /&gt;
#include &amp;quot;Tachyon/TachyonLib.h&amp;quot;&lt;br /&gt;
#include &amp;quot;BCIError.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
using namespace std;&lt;br /&gt;
&lt;br /&gt;
RegisterFilter( TachyonADC, 1 );&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
From the constructor, you request parameters and states that your ADC&lt;br /&gt;
needs;&lt;br /&gt;
from the destructor, you call &amp;lt;tt&amp;gt;Halt&amp;lt;/tt&amp;gt; to make sure that your&lt;br /&gt;
board stops&lt;br /&gt;
acquiring data whenever your class instance gets destructed:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
TachyonADC::TachyonADC()&lt;br /&gt;
: mSourceCh( 0 ),&lt;br /&gt;
  mSampleBlockSize( 0 ),&lt;br /&gt;
  mSamplingRate( 0 )&lt;br /&gt;
{&lt;br /&gt;
  BEGIN_PARAMETER_DEFINITIONS&lt;br /&gt;
    &amp;quot;Source int SourceCh=        64 64 1 128 &amp;quot;&lt;br /&gt;
        &amp;quot;// this is the number of digitized channels&amp;quot;,&lt;br /&gt;
    &amp;quot;Source int SampleBlockSize= 16 5 1 128 &amp;quot;&lt;br /&gt;
        &amp;quot;// this is the number of samples transmitted at a time&amp;quot;,&lt;br /&gt;
    &amp;quot;Source int SamplingRate=    128 128 1 4000 &amp;quot;&lt;br /&gt;
        &amp;quot;// this is the sample rate&amp;quot;,&lt;br /&gt;
  END_PARAMETER_DEFINITIONS&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
TachyonADC::~TachyonADC()&lt;br /&gt;
{&lt;br /&gt;
  Halt();&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==ADC Initialization==&lt;br /&gt;
Your &amp;lt;tt&amp;gt;Preflight&amp;lt;/tt&amp;gt; function will check whether the board works&lt;br /&gt;
with the&lt;br /&gt;
parameters requested, and communicate the dimensions of its output&lt;br /&gt;
signal:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void TachyonADC::Preflight( const SignalProperties&amp;amp;,&lt;br /&gt;
                              SignalProperties&amp;amp; outputProperties )&lt;br /&gt;
                              const&lt;br /&gt;
{&lt;br /&gt;
  if( TACHYON_NO_ERROR != &lt;br /&gt;
        TachyonStart( Parameter( &amp;quot;SamplingRate&amp;quot; ), Parameter( &amp;quot;SourceCh&amp;quot; ) ) )&lt;br /&gt;
    bcierr &amp;lt;&amp;lt; &amp;quot;SamplingRate and/or SourceCh parameters are not compatible&amp;quot;&lt;br /&gt;
           &amp;lt;&amp;lt; &amp;quot; with the A/D card&amp;quot;&lt;br /&gt;
           &amp;lt;&amp;lt; endl;&lt;br /&gt;
  TachyonStop();&lt;br /&gt;
  outputProperties = SignalProperties( Parameter( &amp;quot;SourceCh&amp;quot; ),&lt;br /&gt;
                          Parameter( &amp;quot;SampleBlockSize&amp;quot; ),&lt;br /&gt;
                          SignalType::int16 );&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Here, the last argument of the &amp;lt;tt&amp;gt;SignalProperties&amp;lt;/tt&amp;gt; constructor&lt;br /&gt;
determines not only the type of the signal propagated to the BCI2000&lt;br /&gt;
filters&lt;br /&gt;
but also the format of the &amp;lt;tt&amp;gt;dat&amp;lt;/tt&amp;gt; file written by the source&lt;br /&gt;
module.&lt;br /&gt;
For the &amp;lt;tt&amp;gt;Initialize&amp;lt;/tt&amp;gt; function, it will only be&lt;br /&gt;
called if&lt;br /&gt;
&amp;lt;tt&amp;gt;Preflight&amp;lt;/tt&amp;gt; did not report any errors. If everything works &lt;br /&gt;
fine with&lt;br /&gt;
the parameters, you may skip any checks, and write &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void TachyonADC::Initialize()&lt;br /&gt;
{&lt;br /&gt;
  mSourceCh = Parameter( &amp;quot;SourceCh&amp;quot; );&lt;br /&gt;
  mSampleBlockSize = Parameter( &amp;quot;SampleBlockSize&amp;quot; );&lt;br /&gt;
  mSamplingRate = Parameter( &amp;quot;SamplingRate&amp;quot; );&lt;br /&gt;
  TachyonStart( mSamplingRate, mSourceCh );&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Balancing the &amp;lt;tt&amp;gt;TachyonStart&amp;lt;/tt&amp;gt; call in the &amp;lt;tt&amp;gt;Initialize&amp;lt;/tt&amp;gt; function,&lt;br /&gt;
your &amp;lt;tt&amp;gt;Halt&amp;lt;/tt&amp;gt; function should stop all asynchronous activity that&lt;br /&gt;
your ADC code initiates:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void TachyonADC::Halt()&lt;br /&gt;
{&lt;br /&gt;
  TachyonStop();&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Data Acquisition==&lt;br /&gt;
Note that the function may not return unless the output signal is filled with data, so it is&lt;br /&gt;
crucial that &amp;lt;tt&amp;gt;TachyonWaitForData&amp;lt;/tt&amp;gt; is a blocking function.&lt;br /&gt;
(If your card does not provide such a function, and you need to poll&lt;br /&gt;
for data, don&#039;t forget to call &amp;lt;tt&amp;gt;Sleep( 0 )&amp;lt;/tt&amp;gt; inside your polling loop to&lt;br /&gt;
avoid hogging the CPU.)&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void TachyonADC::Process( const GenericSignal*, GenericSignal* outputSignal )&lt;br /&gt;
{&lt;br /&gt;
  int valuesToRead = mSampleBlockSize * mSourceCh;&lt;br /&gt;
  short* buffer;&lt;br /&gt;
  if( TACHYON_NO_ERROR == TachyonWaitForData( &amp;amp;buffer, valuesToRead ) )&lt;br /&gt;
  {&lt;br /&gt;
    int i = 0;&lt;br /&gt;
    for( int channel = 0; channel &amp;lt; mSourceCh; ++channel )&lt;br /&gt;
      for( int sample = 0; sample &amp;lt; mSampleBlockSize; ++sample )&lt;br /&gt;
        ( *outputSignal )( channel, sample ) = buffer[ i++ ];&lt;br /&gt;
  }&lt;br /&gt;
  else&lt;br /&gt;
    bcierr &amp;lt;&amp;lt; &amp;quot;Error reading data&amp;quot; &amp;lt;&amp;lt; endl;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Finished==&lt;br /&gt;
You are done! Use your &amp;lt;tt&amp;gt;TachyonADC.cpp&amp;lt;/tt&amp;gt; to replace the&lt;br /&gt;
&amp;lt;tt&amp;gt;GenericADC&amp;lt;/tt&amp;gt;&lt;br /&gt;
descendant in an existing source module, add the&lt;br /&gt;
&amp;lt;tt&amp;gt;TachyonADC.lib&amp;lt;/tt&amp;gt; shipped&lt;br /&gt;
with your card to the project, compile, link, and find the bugs...&lt;/div&gt;</summary>
		<author><name>Atennissen</name></author>
	</entry>
	<entry>
		<id>https://www.bci2000.org/mediawiki/index.php?title=Programming_Reference:Rapid_Development&amp;diff=1769</id>
		<title>Programming Reference:Rapid Development</title>
		<link rel="alternate" type="text/html" href="https://www.bci2000.org/mediawiki/index.php?title=Programming_Reference:Rapid_Development&amp;diff=1769"/>
		<updated>2007-05-09T16:07:52Z</updated>

		<summary type="html">&lt;p&gt;Atennissen: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page describes elements of BCI2000 intended to simplify a programmer&#039;s task when implementing a new BCI2000 filter, or application.&lt;br /&gt;
&lt;br /&gt;
==Templates==&lt;br /&gt;
*The [[Programming Reference:Demo Application]] may serve as a starting point for a trial-based application.&lt;br /&gt;
*The [[Programming Reference:IIRFilter]] filter stub allows you to easily implement IIR filters.&lt;br /&gt;
&lt;br /&gt;
==Helper Classes==&lt;br /&gt;
*[[Programming Reference:WavePlayer]] plays audio files.&lt;br /&gt;
*[[Programming Reference:MidiPlayer]] plays MIDI files.&lt;br /&gt;
*[[Programming Reference:TrialStatistics]] computes accuracies and bit rates.&lt;br /&gt;
*[[Programming Reference:LogFile]] transparently maintains a log file in the current data directory.&lt;br /&gt;
&lt;br /&gt;
==Matlab Integration==&lt;br /&gt;
*The [[Programming Reference:MatlabFilter]] lets Matlab scripts act upon BCI2000 data.&lt;/div&gt;</summary>
		<author><name>Atennissen</name></author>
	</entry>
	<entry>
		<id>https://www.bci2000.org/mediawiki/index.php?title=Programming_Reference:Filter_Chain&amp;diff=1768</id>
		<title>Programming Reference:Filter Chain</title>
		<link rel="alternate" type="text/html" href="https://www.bci2000.org/mediawiki/index.php?title=Programming_Reference:Filter_Chain&amp;diff=1768"/>
		<updated>2007-05-09T16:06:09Z</updated>

		<summary type="html">&lt;p&gt;Atennissen: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==The filter chain==&lt;br /&gt;
As noted in the [[Programming Reference:GenericFilter Class|discussion]] of the &amp;lt;tt&amp;gt;GenericFilter::Process&amp;lt;/tt&amp;gt; function, all &amp;lt;tt&amp;gt;GenericFilter&amp;lt;/tt&amp;gt; descendants inside a BCI2000&lt;br /&gt;
module form a single chain of filters. Each filter&#039;s output forms the input of the&lt;br /&gt;
subsequent filter.&lt;br /&gt;
&lt;br /&gt;
==Filter Instantiation==&lt;br /&gt;
Creating instances of all filter classes inside a module, and building the filter chain, is handled by the framework. However, it needs a hint to determine the sequence in which filters are to be arranged. In general, this hint consists of a single statement placed inside your filter&#039;s .cpp file:&amp;lt;pre&amp;gt;&lt;br /&gt;
RegisterFilter( MyFilter, 2.C );&amp;lt;/pre&amp;gt;&lt;br /&gt;
The first argument to this statement is the class name of your filter;&lt;br /&gt;
the second argument is a string value (given without quotes) that determines the&lt;br /&gt;
relative position of your filter in the filter chain.&lt;br /&gt;
This is done by applying the simple rule that the filter positions in the chain match the alphanumeric sorting order of the associated postion strings of the filters. &lt;br /&gt;
This scheme allows you to place an additional filter between existing ones without changing the position strings of the existing filters.&lt;br /&gt;
&lt;br /&gt;
==Signal Processing Filter Instantiation==&lt;br /&gt;
In principle, the above scheme allows to you add filters to a module&#039;s filter chain&lt;br /&gt;
without&lt;br /&gt;
modification to the existing source code, simply by adding a .cpp file&lt;br /&gt;
with a&lt;br /&gt;
&amp;lt;tt&amp;gt;RegisterFilter&amp;lt;/tt&amp;gt; statement to the project.&lt;br /&gt;
However for Signal Processing modules, it is more desirable to&lt;br /&gt;
have an&lt;br /&gt;
explicit representation of the entire filter chain centralized in one&lt;br /&gt;
place.&lt;br /&gt;
So, for each individual Signal Processing module there is one file&lt;br /&gt;
&amp;lt;tt&amp;gt;PipeDefinition.cpp&amp;lt;/tt&amp;gt; that defines the filter chain as a&lt;br /&gt;
sequence of&lt;br /&gt;
&amp;lt;tt&amp;gt;Filter&amp;lt;/tt&amp;gt; statements (see [[Programming Tutorial:Implementing a Signal Processing Filter]] for&lt;br /&gt;
an&lt;br /&gt;
example).&lt;/div&gt;</summary>
		<author><name>Atennissen</name></author>
	</entry>
	<entry>
		<id>https://www.bci2000.org/mediawiki/index.php?title=MARIO_Technical_Documentation&amp;diff=1766</id>
		<title>MARIO Technical Documentation</title>
		<link rel="alternate" type="text/html" href="https://www.bci2000.org/mediawiki/index.php?title=MARIO_Technical_Documentation&amp;diff=1766"/>
		<updated>2007-05-09T15:29:54Z</updated>

		<summary type="html">&lt;p&gt;Atennissen: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==MARIO architecture==&lt;br /&gt;
MARIO is an off-line analysis application developed in MATLAB 7.0.2. It is now modular, object-oriented and can be easily integrated with any other software for data analysis and visualization.&lt;br /&gt;
It can be used in Mu and P300 analyses and allows three kinds of use: users can simply fill the forms of a graphical interface making any choice with a click of its mouse, run a ready-made script or, write up their own scripts according to their needs.&lt;br /&gt;
This set of interfaces allows a wide range of possibilities for a wide range of different analyses.&lt;br /&gt;
&lt;br /&gt;
Internally, the application is composed of 6 main functional modules, each one connected in cascade as in the list below:&lt;br /&gt;
&lt;br /&gt;
*Data import&lt;br /&gt;
*Signal Conditioning&lt;br /&gt;
*Feature Extraction&lt;br /&gt;
*Spectral Extimation&lt;br /&gt;
*Statistical Analysis&lt;br /&gt;
*Visualization&lt;br /&gt;
&lt;br /&gt;
[[Image:arch_blocks.jpg]]&lt;br /&gt;
&lt;br /&gt;
All these modules are hidden in the graphical user interface but they can be distinguished in the batch scripts. Each one of them can be easily replaced with an improved version, a custom version or a different analysis.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Image:Graph.png|thumb|left|Graph of modules]] &lt;br /&gt;
Here you can see a &amp;lt;b&amp;gt;simplified version of the functions graph with their relationships (click to enlarge). &amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Data Import Module==&lt;br /&gt;
&lt;br /&gt;
Any script must have a first module in which to load data that the user wants to analyze.&lt;br /&gt;
There are 3 main types of files containing different groups of information:&lt;br /&gt;
&lt;br /&gt;
*Data files (.dat/.mat)&lt;br /&gt;
*Montage files (.mmf)&lt;br /&gt;
*External Parameter files (.prm) – optional&lt;br /&gt;
&lt;br /&gt;
The data files contain all the data of the BCI session (Mu or P300).&lt;br /&gt;
These data are saved in different files, one for each run, containing 29 trials.&lt;br /&gt;
Internally any file is divided in two main parts: the first part (file header) includes all parameters set by the operator  during the on-line experimentation; the second part contains the EEG signal recorded by the whole set of electrodes on the EEG cap.&lt;br /&gt;
A special function allows data to be loaded from a Matlab file (.mat).&lt;br /&gt;
&lt;br /&gt;
The montage file stores information about the electrode position on the scalp. It consists &lt;br /&gt;
of different sections divided by labels:&lt;br /&gt;
&lt;br /&gt;
#a synthetic name&lt;br /&gt;
#the channel labels&lt;br /&gt;
#a valid channels list&lt;br /&gt;
#the laplacian grid&lt;br /&gt;
#the 3-dimensional spatial coordinates of all the electrodes (this section is optional)&lt;br /&gt;
&lt;br /&gt;
These labelled sections  can be written in the Montage file without a predefined order.&lt;br /&gt;
&lt;br /&gt;
The user can import data from an additional data file, (a parameters file), that can be used if he wants to replace one or more parameters from the BCI2000 ones. For this, it is enough to copy and paste the selected header string in a new prm file, and change its value. &lt;br /&gt;
&lt;br /&gt;
This module is clearly the same for Mu and P300 Analysis.&lt;br /&gt;
&lt;br /&gt;
==Data Conditioning Module==&lt;br /&gt;
&lt;br /&gt;
The MARIO v.2.0 Data Conditioning module allows users to select from a wide range of spatial filters so as to include a custom filter in the user data analysis. The operator can identify which channels or set of channels will give better results at the end of the statistical analysis.&lt;br /&gt;
&lt;br /&gt;
For a Mu analysis, the user can select from four different spatial filter algorithms:&lt;br /&gt;
&lt;br /&gt;
*RAW&lt;br /&gt;
*CAR (Common Average Reference)&lt;br /&gt;
*SMALL LAP&lt;br /&gt;
*LARGE LAP&lt;br /&gt;
&lt;br /&gt;
The first one, (RAW) does not use a filter and analyzes raw recorded data. A user defined analysis will be available on further versions of MARIO.&lt;br /&gt;
&lt;br /&gt;
The Data Conditioning module also allows the the user to compile/modify a list of valid channels on which to conduct any analysis. &lt;br /&gt;
&lt;br /&gt;
P300 Analysis can now use only two of the above spatial filters: the RAW filter and the CAR one. Any other selection will report an unhandled error.&lt;br /&gt;
&lt;br /&gt;
==Feature Extraction Module==&lt;br /&gt;
&lt;br /&gt;
Feature extraction is one of the most important stages of elaboration; it affects any further analysis.&lt;br /&gt;
&lt;br /&gt;
In a Mu rhythm analysis, any feature can be obtained by arranging some of the 12 BCI2000 states.&lt;br /&gt;
The user can now make a choice between two predefined analyses, a simple Mu analysis or an Extended version of the same. The first analysis considers any sample recorded between the cursor appearance on the screen and the end of the trial (when the cursor reaches the right side of the screen).&lt;br /&gt;
The MuExteded analysis instead considers any sample recorded since the target appearance (during the first subset of data, the subject does not have any feedback) until the end of trial.&lt;br /&gt;
In both choices, the statistical analysis will be conduced between two classes of data: the EEG activity recorded while moving up the cursor  (target UP) versus the EEG activity recorded while moving down the cursor (target DOWN).&lt;br /&gt;
Either of these choices will produce different R&amp;lt;sup&amp;gt;2&amp;lt;/sup&amp;gt; values between the corresponding features of the two classes&lt;br /&gt;
&lt;br /&gt;
For a P300 Analysis only two classes are compared and automatically set as frequent events and rare events.&lt;br /&gt;
&lt;br /&gt;
==Spectral Extimation Module &#039;&#039;(for Mu rhythm analysis)&#039;&#039;==&lt;br /&gt;
&lt;br /&gt;
During this step, the program evaluates and analyzes the spectrum of recorded data. &lt;br /&gt;
To do that, the EEG signal is divided into equal length epochs (These epochs can be distinct or overlapped as a percentage of overlap, which the user can set by using the Graphical User Interface or script.)  A spectrum value is evaluated for anyone of these epochs.&lt;br /&gt;
&lt;br /&gt;
At the end of this process, a 3 dimensional matrix (bin × channel × epoch) joined with the one (channel × sample) compiled during a BCI2000 recording session and read by the data import module will be produced.&lt;br /&gt;
&lt;br /&gt;
The algorithm employed to estimate the signal spectrum is the MEM (the same used on-line by BCI2000).&lt;br /&gt;
&lt;br /&gt;
Apart from the percentage of overlap, MARIO allows the user to modify the values of:&lt;br /&gt;
&lt;br /&gt;
#Sampling frequency of recorded data&lt;br /&gt;
#Spatial resolution (delta)&lt;br /&gt;
#Detrending order (Mean or Linear)&lt;br /&gt;
#AR model order&lt;br /&gt;
#Low pass filter frequency&lt;br /&gt;
#High pass filter frequency&lt;br /&gt;
#Filter bandwidth&lt;br /&gt;
#Epoch length&lt;br /&gt;
#Overlap percentage&lt;br /&gt;
&lt;br /&gt;
MARIO v2.0 also computes a virtual states matrix strictly joined with signal one and derived as an arrangement of the BCI2000 states. These states label spectrum samples as valid or not valid and as belonging to one class or another.&lt;br /&gt;
&lt;br /&gt;
==Statistical Analysis Module==&lt;br /&gt;
&lt;br /&gt;
A statistical analysis (presently, R&amp;lt;sup&amp;gt;2&amp;lt;/sup&amp;gt;)  is employed to distinguish between the classes of a BCI2000 task in any trial.&lt;br /&gt;
&lt;br /&gt;
MARIO uses a module that computes the R&amp;lt;sup&amp;gt;2&amp;lt;/sup&amp;gt; value between two classes; these can be TargetUP and TargetDOWN for a Mu rhythm analysis, or frequent events and rare events for a P300 analysis. These data are taken from the spectra matrix (Mu analysis) or from the samples one (P300 analysis) and the regressor vector is yield from BCI2000 states.&lt;br /&gt;
	&lt;br /&gt;
At the end of this analysis, the real index produced (in a range between -1 and 1) is the R&amp;lt;sup&amp;gt;2&amp;lt;/sup&amp;gt; value multiplied by R&amp;lt;sup&amp;gt;2&amp;lt;/sup&amp;gt; sign. If the R&amp;lt;sup&amp;gt;2&amp;lt;/sup&amp;gt; value is near 1, there is an high separability between classes and high performance. If, instead, its value is near 0, it is difficult to distinguish one class from another, and it means low performance.&lt;br /&gt;
&lt;br /&gt;
==Visualization Module==&lt;br /&gt;
&lt;br /&gt;
Mario offers a wide set of visualization graphs that can be combined to have a complete visualization of produced data.&lt;br /&gt;
For a Mu rhythm analysis the user can request to visualize:&lt;br /&gt;
&lt;br /&gt;
#a trajectory plot showing the cursor position for any sample in a  trial BCI2000 as the user saw it on-line&lt;br /&gt;
#a matrix (channel × bin) where the R&amp;lt;sup&amp;gt;2&amp;lt;/sup&amp;gt; value of any feature is shown in a color tint. A colorbar shows the color range between -1 and 1&lt;br /&gt;
#Another panel showing a detail of the previous matrix. The upper topographic plot shows the R&amp;lt;sup&amp;gt;2&amp;lt;/sup&amp;gt; value for any channel in the selected bin of frequencies; the lower one is the spectrum of the selected channel for all the frequencies.&lt;br /&gt;
&lt;br /&gt;
For a P300 analysis the user can choose from:&lt;br /&gt;
&lt;br /&gt;
#An R&amp;lt;sup&amp;gt;2&amp;lt;/sup&amp;gt; matrix&lt;br /&gt;
#An amplitude waveform graph&lt;br /&gt;
#A topographic plot&lt;br /&gt;
#An ERP response graph&lt;br /&gt;
#A string prediction form.&lt;br /&gt;
&lt;br /&gt;
All these result visualizations can be easily included in any of the user scripts for custom analysis.&lt;/div&gt;</summary>
		<author><name>Atennissen</name></author>
	</entry>
	<entry>
		<id>https://www.bci2000.org/mediawiki/index.php?title=MARIO_Technical_Documentation&amp;diff=1765</id>
		<title>MARIO Technical Documentation</title>
		<link rel="alternate" type="text/html" href="https://www.bci2000.org/mediawiki/index.php?title=MARIO_Technical_Documentation&amp;diff=1765"/>
		<updated>2007-05-09T15:28:25Z</updated>

		<summary type="html">&lt;p&gt;Atennissen: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==MARIO architecture==&lt;br /&gt;
MARIO is an off-line analysis application developed in MATLAB 7.0.2. It is now modular, object-oriented and can be easily integrated with any other software for data analysis and visualization.&lt;br /&gt;
It can be used in Mu and P300 analyses and allows three kinds of use: users can simply fill the forms of a graphical interface making any choice with a click of its mouse, run a ready-made script or, write up their own scripts according to their needs.&lt;br /&gt;
This set of interfaces allows a wide range of possibilities for a wide range of different analyses.&lt;br /&gt;
&lt;br /&gt;
Internally, the application is composed of 6 main functional modules, each one connected in cascade as in the list below:&lt;br /&gt;
&lt;br /&gt;
*Data import&lt;br /&gt;
*Signal Conditioning&lt;br /&gt;
*Feature Extraction&lt;br /&gt;
*Spectral Extimation&lt;br /&gt;
*Statistical Analysis&lt;br /&gt;
*Visualization&lt;br /&gt;
&lt;br /&gt;
[[Image:arch_blocks.jpg]]&lt;br /&gt;
&lt;br /&gt;
All these modules are hidden in the graphical user interface but they can be distinguished in the batch scripts. Each one of them can be easily replaced with an improved version, a custom version or a different analysis.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Image:Graph.png|thumb|left|Graph of modules]] &lt;br /&gt;
Here you can see a &amp;lt;b&amp;gt;simplified version of the functions graph with their relationships (click to enlarge). &amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Data Import Module==&lt;br /&gt;
&lt;br /&gt;
Any script must have a first module in which to load data that the user wants to analyze.&lt;br /&gt;
There are 3 main types of files containing different groups of information:&lt;br /&gt;
&lt;br /&gt;
*Data files (.dat/.mat)&lt;br /&gt;
*Montage files (.mmf)&lt;br /&gt;
*External Parameter files (.prm) – optional&lt;br /&gt;
&lt;br /&gt;
The data files contain all the data of the BCI session (Mu or P300).&lt;br /&gt;
These data are saved in different files, one for each run, containing 29 trials.&lt;br /&gt;
Internally any file is divided in two main parts: the first part (file header) includes all parameters set by the operator  during the on-line experimentation; the second part contains the EEG signal recorded by the whole set of electrodes on the EEG cap.&lt;br /&gt;
A special function allows data to be loaded from a Matlab file (.mat).&lt;br /&gt;
&lt;br /&gt;
The montage file stores information about the electrode position on the scalp. It consists &lt;br /&gt;
of different sections divided by labels:&lt;br /&gt;
&lt;br /&gt;
#a synthetic name&lt;br /&gt;
#the channel labels&lt;br /&gt;
#a valid channels list&lt;br /&gt;
#the laplacian grid&lt;br /&gt;
#the 3-dimensional spatial coordinates of all the electrodes (this section is optional)&lt;br /&gt;
&lt;br /&gt;
These labelled sections  can be written in the Montage file without a predefined order.&lt;br /&gt;
&lt;br /&gt;
The user can import data from an additional data file, (a parameters file), that can be used if he wants to replace one or more parameters from the BCI2000 ones. For this, it is enough to copy and paste the selected header string in a new prm file, and change its value. &lt;br /&gt;
&lt;br /&gt;
This module is clearly the same for Mu and P300 Analysis.&lt;br /&gt;
&lt;br /&gt;
==Data Conditioning Module==&lt;br /&gt;
&lt;br /&gt;
The MARIO v.2.0 Data Conditioning module allows users to select from a wide range of spatial filters so as to include a custom filter in the user data analysis. The operator can identify which channels or set of channels will give better results at the end of the statistical analysis.&lt;br /&gt;
&lt;br /&gt;
For a Mu analysis, the user can select from four different spatial filter algorithms:&lt;br /&gt;
&lt;br /&gt;
*RAW&lt;br /&gt;
*CAR (Common Average Reference)&lt;br /&gt;
*SMALL LAP&lt;br /&gt;
*LARGE LAP&lt;br /&gt;
&lt;br /&gt;
The first one (RAW) does not use a filter and analyzes raw recorded data. A user defined analysis will be available on further versions of MARIO.&lt;br /&gt;
&lt;br /&gt;
The Data Conditioning module also allows the the user to compile/modify a list of valid channels on which to conduct any analysis. &lt;br /&gt;
&lt;br /&gt;
P300 Analysis can now use only two of the above spatial filters: the RAW filter and the CAR one. Any other selection will report an unhandled error.&lt;br /&gt;
&lt;br /&gt;
==Feature Extraction Module==&lt;br /&gt;
&lt;br /&gt;
Feature extraction is one of the most important stages of elaboration; it affects any further analysis.&lt;br /&gt;
&lt;br /&gt;
In a Mu rhythm analysis, any feature can be obtained by arranging some of the 12 BCI2000 states.&lt;br /&gt;
The user can now make a choice between two predefined analyses, a simple Mu analysis or an Extended version of the same. The first analysis considers any sample recorded between the cursor appearance on the screen and the end of the trial (when the cursor reaches the right side of the screen).&lt;br /&gt;
The MuExteded analysis instead considers any sample recorded since the target appearance (during the first subset of data, the subject does not have any feedback) until the end of trial.&lt;br /&gt;
In both choices, the statistical analysis will be conduced between two classes of data: the EEG activity recorded while moving up the cursor  (target UP) versus the EEG activity recorded while moving down the cursor (target DOWN).&lt;br /&gt;
Either of these choices will produce different R&amp;lt;sup&amp;gt;2&amp;lt;/sup&amp;gt; values between the corresponding features of the two classes&lt;br /&gt;
&lt;br /&gt;
For a P300 Analysis only two classes are compared and automatically set as frequent events and rare events.&lt;br /&gt;
&lt;br /&gt;
==Spectral Extimation Module &#039;&#039;(for Mu rhythm analysis)&#039;&#039;==&lt;br /&gt;
&lt;br /&gt;
During this step, the program evaluates and analyzes the spectrum of recorded data. &lt;br /&gt;
To do that, the EEG signal is divided into equal length epochs (These epochs can be distinct or overlapped as a percentage of overlap, which the user can set by using the Graphical User Interface or script.)  A spectrum value is evaluated for anyone of these epochs.&lt;br /&gt;
&lt;br /&gt;
At the end of this process, a 3 dimensional matrix (bin × channel × epoch) joined with the one (channel × sample) compiled during a BCI2000 recording session and read by the data import module will be produced.&lt;br /&gt;
&lt;br /&gt;
The algorithm employed to estimate the signal spectrum is the MEM (the same used on-line by BCI2000).&lt;br /&gt;
&lt;br /&gt;
Apart from the percentage of overlap, MARIO allows the user to modify the values of:&lt;br /&gt;
&lt;br /&gt;
#Sampling frequency of recorded data&lt;br /&gt;
#Spatial resolution (delta)&lt;br /&gt;
#Detrending order (Mean or Linear)&lt;br /&gt;
#AR model order&lt;br /&gt;
#Low pass filter frequency&lt;br /&gt;
#High pass filter frequency&lt;br /&gt;
#Filter bandwidth&lt;br /&gt;
#Epoch length&lt;br /&gt;
#Overlap percentage&lt;br /&gt;
&lt;br /&gt;
MARIO v2.0 also computes a virtual states matrix strictly joined with signal one and derived as an arrangement of the BCI2000 states. These states label spectrum samples as valid or not valid and as belonging to one class or another.&lt;br /&gt;
&lt;br /&gt;
==Statistical Analysis Module==&lt;br /&gt;
&lt;br /&gt;
A statistical analysis (presently, R&amp;lt;sup&amp;gt;2&amp;lt;/sup&amp;gt;)  is employed to distinguish between the classes of a BCI2000 task in any trial.&lt;br /&gt;
&lt;br /&gt;
MARIO uses a module that computes the R&amp;lt;sup&amp;gt;2&amp;lt;/sup&amp;gt; value between two classes; these can be TargetUP and TargetDOWN for a Mu rhythm analysis, or frequent events and rare events for a P300 analysis. These data are taken from the spectra matrix (Mu analysis) or from the samples one (P300 analysis) and the regressor vector is yield from BCI2000 states.&lt;br /&gt;
	&lt;br /&gt;
At the end of this analysis, the real index produced (in a range between -1 and 1) is the R&amp;lt;sup&amp;gt;2&amp;lt;/sup&amp;gt; value multiplied by R&amp;lt;sup&amp;gt;2&amp;lt;/sup&amp;gt; sign. If the R&amp;lt;sup&amp;gt;2&amp;lt;/sup&amp;gt; value is near 1, there is an high separability between classes and high performance. If, instead, its value is near 0, it is difficult to distinguish one class from another, and it means low performance.&lt;br /&gt;
&lt;br /&gt;
==Visualization Module==&lt;br /&gt;
&lt;br /&gt;
Mario offers a wide set of visualization graphs that can be combined to have a complete visualization of produced data.&lt;br /&gt;
For a Mu rhythm analysis the user can request to visualize:&lt;br /&gt;
&lt;br /&gt;
#a trajectory plot showing the cursor position for any sample in a  trial BCI2000 as the user saw it on-line&lt;br /&gt;
#a matrix (channel × bin) where the R&amp;lt;sup&amp;gt;2&amp;lt;/sup&amp;gt; value of any feature is shown in a color tint. A colorbar shows the color range between -1 and 1&lt;br /&gt;
#Another panel showing a detail of the previous matrix. The upper topographic plot shows the R&amp;lt;sup&amp;gt;2&amp;lt;/sup&amp;gt; value for any channel in the selected bin of frequencies; the lower one is the spectrum of the selected channel for all the frequencies.&lt;br /&gt;
&lt;br /&gt;
For a P300 analysis the user can choose from:&lt;br /&gt;
&lt;br /&gt;
#An R&amp;lt;sup&amp;gt;2&amp;lt;/sup&amp;gt; matrix&lt;br /&gt;
#An amplitude waveform graph&lt;br /&gt;
#A topographic plot&lt;br /&gt;
#An ERP response graph&lt;br /&gt;
#A string prediction form.&lt;br /&gt;
&lt;br /&gt;
All these result visualizations can be easily included in any of the user scripts for custom analysis.&lt;/div&gt;</summary>
		<author><name>Atennissen</name></author>
	</entry>
	<entry>
		<id>https://www.bci2000.org/mediawiki/index.php?title=MARIO_Technical_Documentation&amp;diff=1764</id>
		<title>MARIO Technical Documentation</title>
		<link rel="alternate" type="text/html" href="https://www.bci2000.org/mediawiki/index.php?title=MARIO_Technical_Documentation&amp;diff=1764"/>
		<updated>2007-05-09T15:26:23Z</updated>

		<summary type="html">&lt;p&gt;Atennissen: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==MARIO architecture==&lt;br /&gt;
MARIO is an off-line analysis application developed in MATLAB 7.0.2. It is now modular, object-oriented and can be easily integrated with any other software for data analysis and visualization.&lt;br /&gt;
It can be used in Mu and P300 analyses and allows three kinds of use: users can simply fill the forms of a graphical interface making any choice with a click of its mouse, run a ready-made script or, write up their own scripts according to their needs.&lt;br /&gt;
This set of interfaces allows a wide range of possibilities for a wide range of different analyses.&lt;br /&gt;
&lt;br /&gt;
Internally, the application is composed of 6 main functional modules, each one connected in cascade as in the list below:&lt;br /&gt;
&lt;br /&gt;
*Data import&lt;br /&gt;
*Signal Conditioning&lt;br /&gt;
*Feature Extraction&lt;br /&gt;
*Spectral Extimation&lt;br /&gt;
*Statistical Analysis&lt;br /&gt;
*Visualization&lt;br /&gt;
&lt;br /&gt;
[[Image:arch_blocks.jpg]]&lt;br /&gt;
&lt;br /&gt;
All these modules are hidden in the graphical user interface but they can be distinguished in the batch scripts. Each one of them can be easily replaced with an improved version, a custom version or a different analysis.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Image:Graph.png|thumb|left|Graph of modules]] &lt;br /&gt;
Here you can see a &amp;lt;b&amp;gt;simplified version of the functions graph with their relationships (click to enlarge). &amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Data Import Module==&lt;br /&gt;
&lt;br /&gt;
Any script must have a first module in which to load data that the user wants to analyze.&lt;br /&gt;
There are 3 main types of files containing different groups of information:&lt;br /&gt;
&lt;br /&gt;
*Data files (.dat/.mat)&lt;br /&gt;
*Montage files (.mmf)&lt;br /&gt;
*External Parameter files (.prm) – optional&lt;br /&gt;
&lt;br /&gt;
The data files contain all the data of the BCI session (Mu or P300).&lt;br /&gt;
These data are saved in different files, one for each run, containing 29 trials.&lt;br /&gt;
Internally any file is divided in two main parts: the first part (file header) includes all parameters set by the operator  during the on-line experimentation; the second part contains the EEG signal recorded by the whole set of electrodes on the EEG cap.&lt;br /&gt;
A special function allows data to be loaded from a Matlab file (.mat).&lt;br /&gt;
&lt;br /&gt;
The montage file stores information about the electrode position on the scalp. It consists &lt;br /&gt;
of different sections divided by labels:&lt;br /&gt;
&lt;br /&gt;
#a synthetic name&lt;br /&gt;
#the channel labels&lt;br /&gt;
#a valid channels list&lt;br /&gt;
#the laplacian grid&lt;br /&gt;
#the 3-dimensional spatial coordinates of all the electrodes (this section is optional)&lt;br /&gt;
&lt;br /&gt;
These labelled sections  can be written in the Montage file without a predefined order.&lt;br /&gt;
&lt;br /&gt;
The user can import data from an additional data file, (a parameters file), that can be used if he wants to replace one or more parameters from the BCI2000 ones. For this, it is enough to copy and paste the selected header string in a new prm file, and change its value. &lt;br /&gt;
&lt;br /&gt;
This module is clearly the same for Mu and P300 Analysis.&lt;br /&gt;
&lt;br /&gt;
==Data Conditioning Module==&lt;br /&gt;
&lt;br /&gt;
The MARIO v.2.0 Data Conditioning module allows users to select from a wide range of spatial filters so as to include a custom filter in the user data analysis. The operator can identify which channels or set of channels will give better results at the end of the statistical analysis.&lt;br /&gt;
&lt;br /&gt;
For a Mu analysis, the user can select from four different spatial filter algorithms:&lt;br /&gt;
&lt;br /&gt;
*RAW&lt;br /&gt;
*CAR (Common Average Reference)&lt;br /&gt;
*SMALL LAP&lt;br /&gt;
*LARGE LAP&lt;br /&gt;
&lt;br /&gt;
The first one (RAW) does not use a filter and analyzes raw recorded data. A user defined analysis will be available on further versions of MARIO.&lt;br /&gt;
&lt;br /&gt;
The Data Conditioning module also allows the the user to compile/modify a list of valid channels on which to conduct any analysis. &lt;br /&gt;
&lt;br /&gt;
P300 Analysis can now use only two of the above spatial filters: the RAW filter and the CAR one. Any other selection will report an unhandled error.&lt;br /&gt;
&lt;br /&gt;
==Feature Extraction Module==&lt;br /&gt;
&lt;br /&gt;
Feature extraction is one of the most important stages of elaboration; it affects any further analysis.&lt;br /&gt;
&lt;br /&gt;
In a Mu rhythm analysis, any feature can be obtained by arranging some of the 12 BCI2000 states.&lt;br /&gt;
The user can now make a choice between two predefined analyses, a simple Mu analysis or an Extended version of the same. The first analysis considers any sample recorded between the cursor appearance on the screen and the end of the trial (when the cursor reaches the right side of the screen).&lt;br /&gt;
The MuExteded analysis instead considers any sample recorded since the target appearance (during the first subset of data, the subject does not have any feedback) until the end of trial.&lt;br /&gt;
In both choices, the statistical analysis will be conduced between two classes of data: the EEG activity recorded while moving up the cursor  (target UP) versus the EEG activity recorded while moving down the cursor (target DOWN).&lt;br /&gt;
Either of these choices will produce different R&amp;lt;sup&amp;gt;2&amp;lt;/sup&amp;gt; values between the corresponding features of the two classes&lt;br /&gt;
&lt;br /&gt;
For a P300 Analysis only two classes are compared and automatically set as frequent events and rare events.&lt;br /&gt;
&lt;br /&gt;
==Spectral Extimation Module &#039;&#039;(for Mu rhythm analysis)&#039;&#039;==&lt;br /&gt;
&lt;br /&gt;
During this step, the program evaluates and analyzes the spectrum of recorded data. &lt;br /&gt;
To do that, the EEG signal is divided into equal length epochs (These epochs can be distinct or overlapped as a percentage of overlap, which the user can set by using the Graphical User Interface or script.)  A spectrum value is evaluated for anyone of these epochs.&lt;br /&gt;
&lt;br /&gt;
At the end of this process, a 3 dimensional matrix (bin × channel × epoch) joined with the one (channel × sample) compiled during a BCI2000 recording session and read by the data import module will be produced.&lt;br /&gt;
&lt;br /&gt;
The algorithm employed to estimate the signal spectrum is the MEM (the same used on-line by BCI2000).&lt;br /&gt;
&lt;br /&gt;
Apart from the percentage of overlap, MARIO allows the user to modify the values of:&lt;br /&gt;
&lt;br /&gt;
#Sampling frequency of recorded data&lt;br /&gt;
#Spatial resolution (delta)&lt;br /&gt;
#Detrending order (Mean or Linear)&lt;br /&gt;
#AR model order&lt;br /&gt;
#Low pass filter frequency&lt;br /&gt;
#High pass filter frequency&lt;br /&gt;
#Filter bandwidth&lt;br /&gt;
#Epoch length&lt;br /&gt;
#Overlap percentage&lt;br /&gt;
&lt;br /&gt;
MARIO v2.0 also computes a virtual states matrix strictly joined with signal one and derived as an arrangement of the BCI2000 states. These states label spectrum samples as valid or not valid and as belonging to one class or another.&lt;br /&gt;
&lt;br /&gt;
==Statistical Analysis Module==&lt;br /&gt;
&lt;br /&gt;
A statistical analysis (presently, R&amp;lt;sup&amp;gt;2&amp;lt;/sup&amp;gt;)  is employed to distinguish between the classes of a BCI2000 task in any trial.&lt;br /&gt;
&lt;br /&gt;
MARIO uses a module that computes the R&amp;lt;sup&amp;gt;2&amp;lt;/sup&amp;gt; value between two classes; these can be TargetUP and TargetDOWN for a Mu rhythm analysis, or frequent events and rare events for a P300 analysis. These data are taken from the spectra matrix (Mu analysis) or from the samples one (P300 analysis) and the regressor vector is yield from BCI2000 states.&lt;br /&gt;
	&lt;br /&gt;
At the end of this analysis, the real index produced (in a range between -1 and 1) is the R&amp;lt;sup&amp;gt;2&amp;lt;/sup&amp;gt; value multiplied by R&amp;lt;sup&amp;gt;2&amp;lt;/sup&amp;gt; sign. If the R&amp;lt;sup&amp;gt;2&amp;lt;/sup&amp;gt; value is near 1, there is an high separability between classes and high performance. If, instead, its value is near 0, it is difficult to distinguish one class from another, and it means low performance.&lt;br /&gt;
&lt;br /&gt;
==Visualization Module==&lt;br /&gt;
&lt;br /&gt;
Mario offers a wide set of visualization graphs that can be combined to have a complete visualization of produced data.&lt;br /&gt;
For a Mu rhythm analysis user can request to visualize:&lt;br /&gt;
&lt;br /&gt;
#a trajectory plot showing the cursor position for any sample in a  trial BCI2000 as user saw it on-line&lt;br /&gt;
#a matrix (channel × bin) where the R&amp;lt;sup&amp;gt;2&amp;lt;/sup&amp;gt; value of any feature is shown in a color tint. A colorbar shows the color range between -1 and 1&lt;br /&gt;
#Another panel showing a detail of the previous matrix. The upper topographic plot shows the R&amp;lt;sup&amp;gt;2&amp;lt;/sup&amp;gt; value for any channel in the selected bin of frequencies; the lower one is the spectrum of the selected channel for all the frequencies.&lt;br /&gt;
&lt;br /&gt;
For a P300 analysis user can choose from:&lt;br /&gt;
&lt;br /&gt;
#An R&amp;lt;sup&amp;gt;2&amp;lt;/sup&amp;gt; matrix&lt;br /&gt;
#An amplitude waveform graph&lt;br /&gt;
#A topographic plot&lt;br /&gt;
#An ERP response graph&lt;br /&gt;
#A string prediction form.&lt;br /&gt;
&lt;br /&gt;
All these result visualizations can be easily included in any of user scripts for custom analysis.&lt;/div&gt;</summary>
		<author><name>Atennissen</name></author>
	</entry>
	<entry>
		<id>https://www.bci2000.org/mediawiki/index.php?title=Programming_Reference:Localization&amp;diff=1763</id>
		<title>Programming Reference:Localization</title>
		<link rel="alternate" type="text/html" href="https://www.bci2000.org/mediawiki/index.php?title=Programming_Reference:Localization&amp;diff=1763"/>
		<updated>2007-05-09T14:21:16Z</updated>

		<summary type="html">&lt;p&gt;Atennissen: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== &#039;&#039;&#039;Introduction&#039;&#039;&#039; ==&lt;br /&gt;
As BCI2000 modules are being used in various countries, there emerges some need to adapt user interface elements to regional customs. Most notably, text that gives information to the subject requires translation into the subject&#039;s native language, as often a knowledge of English cannot be assumed. Even with a knowledge of Englisn, reading text in a foreign language is a distracting factor that makes the already demanding task of operating a BCI even more difficult.&lt;br /&gt;
&lt;br /&gt;
This document explains the approach taken to manage localized (translated) user interface strings in BCI2000 application modules, trying to meet the following goals:&lt;br /&gt;
&lt;br /&gt;
*&#039;&#039;&#039;Flexibility:&#039;&#039;&#039;  For the end user (operator), it should be possible to add translations into a language that are not provided inside an application module, and to modify translations he does not feel to be appropriate. This should be achievable without making changes to the source code and recompiling the application module. &lt;br /&gt;
*&#039;&#039;&#039;Separability:&#039;&#039;&#039;  For the user, switching languages should be done at a central place, i.e., by changing a single parameter. For the programmer, adding localization capabilities to existing modules should be possible with minimal changes to existing code. When writing new application modules, there should be no need to consider localization issues in advance.&lt;br /&gt;
*&#039;&#039;&#039;Documentation:&#039;&#039;&#039; Documenting and providing a collection of existing translations into various languages should be possible inside a module&#039;s source code.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== &#039;&#039;&#039;Strategies&#039;&#039;&#039; ==&lt;br /&gt;
&lt;br /&gt;
For a number of text values that have always been set from parameters (such as the Speller module&#039;s &amp;lt;tt&amp;gt;Goal&amp;lt;/tt&amp;gt; parameter that holds the text the user is told to spell in copy spelling mode), localization is not an issue because the user may just change the value as seems appropriate.&lt;br /&gt;
    &lt;br /&gt;
The remaining text items, according to the way they are specified, fall into two categories:&lt;br /&gt;
&lt;br /&gt;
# C string literals in &amp;lt;tt&amp;gt;*.cpp&amp;lt;/tt&amp;gt; source files, and &lt;br /&gt;
# text fields in GUI resource files (such as Borland &amp;lt;tt&amp;gt;*.dfm&amp;lt;/tt&amp;gt; files). &lt;br /&gt;
&lt;br /&gt;
For both categories, translations are kept in a single matrix type parameter that uses string labels, i.e., row and column titles. Each column title represents the native English version of a text; row titles represent languages for which translations exist. The user chooses amongst languages by specifying the desired language in a second parameter; the BCI2000 framework will then use this table to look up a text&#039;s translation, matching the text itself against column labels, and &lt;br /&gt;
the target language against row labels. If no match is found, it will leave the text unchanged.&lt;br /&gt;
&lt;br /&gt;
For string literals in &amp;lt;tt&amp;gt;*.cpp&amp;lt;/tt&amp;gt; files, the strategy is to simply put a function layer around the string, i.e., to send it through a function that checks for a translation and exchanges the text if there is a match. Introducing localizability into existing code implies only a very small amount of change compared to, e.g., introducing a separate parameter for each string. In the former case, one needs only wrap the string literal into a function call in-place; in the latter case, one would have to add a parameter line to a possibly remote filter class constructor, read that parameter from inside that filter&#039;s &amp;lt;tt&amp;gt;Initialize()&amp;lt;/tt&amp;gt; call, and put it into the object that actually holds the string which might require introduction of additional accessor functions.&lt;br /&gt;
&lt;br /&gt;
For strings specified in GUI resource files, the strategy is to supply a function that, very generally, examines string properties of GUI objects, replacing them with their localized versions if applicable.&lt;br /&gt;
This function needs to be called explicitly from inside the &amp;lt;tt&amp;gt;Initialize()&amp;lt;/tt&amp;gt; function of the &amp;lt;tt&amp;gt;GenericFilter&amp;lt;/tt&amp;gt; descendant that determines the GUI object&#039;s behavior (in most cases, this is the application module&#039;s &amp;lt;tt&amp;gt;TTask&amp;lt;/tt&amp;gt; class).&lt;br /&gt;
&lt;br /&gt;
 &lt;br /&gt;
==  &#039;&#039;&#039;Implementation&#039;&#039;&#039; ==&lt;br /&gt;
&lt;br /&gt;
The implementation is centered around a &amp;lt;tt&amp;gt;Localization&amp;lt;/tt&amp;gt; class declared in &amp;lt;tt&amp;gt;Application/shared/Localization.h&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== &#039;&#039;&#039;Interface to the operator user&#039;&#039;&#039; ===&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;tt&amp;gt;Localization&amp;lt;/tt&amp;gt; class adds two parameters to the system that govern its localization&lt;br /&gt;
behavior: &lt;br /&gt;
&#039;&#039;&#039;*&#039;&#039;&#039; &amp;lt;tt&amp;gt;Language&amp;lt;/tt&amp;gt; defines the language into which strings are translated; if its value matches one of the &amp;lt;tt&amp;gt;LocalizedStrings&amp;lt;/tt&amp;gt; row labels, translations will be taken from that row; otherwise, strings will not be translated. A value of &amp;lt;tt&amp;gt;Default&amp;lt;/tt&amp;gt; results in all strings keeping their original values. &lt;br /&gt;
&#039;&#039;&#039;*&#039;&#039;&#039; &amp;lt;tt&amp;gt;LocalizedStrings&amp;lt;/tt&amp;gt; defines string translations. Strings that do not appear as a column label will not be translated. Also, strings with an empty translation entry in &amp;lt;tt&amp;gt;LocalizedStrings&amp;lt;/tt&amp;gt; will not be translated.&lt;br /&gt;
&lt;br /&gt;
===&#039;&#039;&#039;Interface to the programmer&#039;&#039;&#039;===&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;tt&amp;gt;LocalizedStrings&amp;lt;/tt&amp;gt; parameter is empty by default. Although a user may add translations in desired languages to the empty matrix by manually using the matrix editor of the operator module, translations will preferably be provided in a filter constructor by listing them as in the following example:&lt;br /&gt;
&lt;br /&gt;
 #include &amp;quot;Localization.h&amp;quot;&lt;br /&gt;
 ...&lt;br /&gt;
 TTask::TTask()&lt;br /&gt;
   {&lt;br /&gt;
   ...&lt;br /&gt;
   LANGUAGES &amp;quot;Italian&amp;quot;,&lt;br /&gt;
             &amp;quot;French&amp;quot;,&lt;br /&gt;
   BEGIN_LOCALIZED_STRINGS&lt;br /&gt;
    &amp;quot;Yes&amp;quot;,&lt;br /&gt;
             &amp;quot;Si&amp;quot;,&lt;br /&gt;
             &amp;quot;Oui&amp;quot;,&lt;br /&gt;
     &amp;quot;No&amp;quot;,&lt;br /&gt;
             &amp;quot;No&amp;quot;,&lt;br /&gt;
             &amp;quot;Non&amp;quot;,&lt;br /&gt;
   END_LOCALIZED_STRINGS&lt;br /&gt;
   ...&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
If the &amp;lt;tt&amp;gt;LocalizedStrings&amp;lt;/tt&amp;gt; matrix was empty before the &amp;lt;tt&amp;gt;TTask&amp;lt;/tt&amp;gt; constructor gets called, it will have these entries after execution of the constructor:&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
|&lt;br /&gt;
|Yes&lt;br /&gt;
|No&lt;br /&gt;
|-&lt;br /&gt;
|Italian&lt;br /&gt;
|Si&lt;br /&gt;
|No&lt;br /&gt;
|-&lt;br /&gt;
|French&lt;br /&gt;
|Oui &lt;br /&gt;
|Non&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
There may be any number of translation tables inside filter constructors, with their entries being added to the existing ones, or overriding entries that already exist.&lt;br /&gt;
&lt;br /&gt;
Once entered, the translations contained in &amp;lt;tt&amp;gt;LocalizedStrings&amp;lt;/tt&amp;gt; are applied via two mechanisms:&lt;br /&gt;
&lt;br /&gt;
*The function &amp;lt;tt&amp;gt;LocalizableString()&amp;lt;/tt&amp;gt; takes a string as an argument and returns the appropriate entry from &amp;lt;tt&amp;gt;LocalizedStrings&amp;lt;/tt&amp;gt;, or the unmodified string if no entry can be found. For example, instead of &lt;br /&gt;
&amp;lt;tt&amp;gt;TellUser( &amp;quot;Well done!&amp;quot; );&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;one would write&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;#include &amp;quot;Localization.h&amp;quot;&amp;lt;br&amp;gt;...&amp;lt;br&amp;gt;TellUser( LocalizableString( &amp;quot;Well done!&amp;quot; ) );&amp;lt;br&amp;gt;&amp;lt;/tt&amp;gt;to have a translation for &amp;quot;Well done!&amp;quot; looked up in &amp;lt;tt&amp;gt;LocalizedStrings&amp;lt;/tt&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
* The function &amp;lt;tt&amp;gt;ApplyLocalizations()&amp;lt;/tt&amp;gt; takes a pointer to a GUI object (usually a VCL &amp;lt;tt&amp;gt;TForm*&amp;lt;/tt&amp;gt;) and translates all localizable text contained within it. This function must be called during &amp;lt;tt&amp;gt;GenericFilter:: Initialize&amp;lt;/tt&amp;gt; for each GUI object generated from a resource file.&lt;br /&gt;
&lt;br /&gt;
===&#039;&#039;&#039;Further implementation details&#039;&#039;&#039;===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;*&#039;&#039;&#039; You should not use &amp;lt;tt&amp;gt;LocalizableString()&amp;lt;/tt&amp;gt; on string constants used before the first call to &amp;lt;tt&amp;gt;GenericFilter::Initialize()&amp;lt;/tt&amp;gt; or for initializing static or global objects of any kind because localization information used will not be available at global initialization time, and local static variables, once initialized, will not be updated appropriately. &lt;br /&gt;
    &lt;br /&gt;
&#039;&#039;&#039;*&#039;&#039;&#039; Language names are case-insensitive. You may use any string for a language name but as a convention we suggest its most common English name, as in &amp;lt;tt&amp;gt;Italian, Dutch, French, German&amp;lt;/tt&amp;gt;, with international country abbreviations as optional regional qualifiers as in &amp;lt;tt&amp;gt;EnglishUS, EnglishGB, GermanA, GermanCH&amp;lt;/tt&amp;gt; if necessary. &lt;br /&gt;
&lt;br /&gt;
[[Image:table.png|center|thumb|300px|table]]&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;*&#039;&#039;&#039; Encoding of non-ASCII characters follows the UTF8 convention. To ensure platform independent readability of source code files, there are macros that define HTML character names to their UTF8 encoded strings. This allows you to write&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tt&amp;gt;&amp;quot;Sm&amp;quot; oslash &amp;quot;rrebr&amp;quot; oslash &amp;quot;d&amp;quot;&amp;lt;/tt&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
for &amp;quot;Smørrebrød&amp;quot; (cf. table 1).&lt;/div&gt;</summary>
		<author><name>Atennissen</name></author>
	</entry>
	<entry>
		<id>https://www.bci2000.org/mediawiki/index.php?title=Programming_Reference:Error_Handling&amp;diff=1762</id>
		<title>Programming Reference:Error Handling</title>
		<link rel="alternate" type="text/html" href="https://www.bci2000.org/mediawiki/index.php?title=Programming_Reference:Error_Handling&amp;diff=1762"/>
		<updated>2007-05-08T20:31:23Z</updated>

		<summary type="html">&lt;p&gt;Atennissen: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==&#039;&#039;&#039;Handling Errors&#039;&#039;&#039;==&lt;br /&gt;
&lt;br /&gt;
===&#039;&#039;&#039;Types of Errors&#039;&#039;&#039;===&lt;br /&gt;
&lt;br /&gt;
We assume that all errors we need to consider fall into one of the following categories, each of which implies a different type of approach to error avoidance/error handling:&lt;br /&gt;
&lt;br /&gt;
*Parameter Setup Errors&lt;br /&gt;
&lt;br /&gt;
*Runtime Errors&lt;br /&gt;
&lt;br /&gt;
*Logic (Programming) Errors &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===&#039;&#039;&#039;Parameter Setup Errors&#039;&#039;&#039;===&lt;br /&gt;
&lt;br /&gt;
====&#039;&#039;&#039;Definition of the Term&#039;&#039;&#039;====&lt;br /&gt;
This category covers anything a user can do wrong by using a program with parameters that are out of range, inconsistent, or otherwise erroneous (e.g., by specifying an output file at a location where the user has no write permission).&lt;br /&gt;
&lt;br /&gt;
Parameter setup errors, when unhandled, become runtime errors.&lt;br /&gt;
&lt;br /&gt;
====&#039;&#039;&#039;Strategies&#039;&#039;&#039;====&lt;br /&gt;
&lt;br /&gt;
As a guideline for approaching Parameter Setup Errors we adopt the following principle: &amp;quot;Whatever a&lt;br /&gt;
user does from within an application program should never make that application crash.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
In BCI 2000, this translates into a thorough parameter check done by each module before any parameter settings are actually applied to the system.&lt;br /&gt;
&lt;br /&gt;
Parameter checking should comprise&lt;br /&gt;
&lt;br /&gt;
*Range and Consistency checks, whereby ranges generally depend on the values of other parameters; &lt;br /&gt;
&lt;br /&gt;
*Signal property checks: Does the output signal of one filter meet the next filter&#039;s requirements for its input signal?&lt;br /&gt;
&lt;br /&gt;
*Resource availability checks:&lt;br /&gt;
&lt;br /&gt;
-Are needed system resources available? (E.g., is it possible to open a required sound output device?)&lt;br /&gt;
&lt;br /&gt;
-Are auxiliary files (e.g., media files) available and readable?&lt;br /&gt;
&lt;br /&gt;
-Do output files have legal file names? Are output files writeable? (We could even check whether&lt;br /&gt;
there is enough space left to write the EEG file, but this is not practical because a &lt;br /&gt;
concurrent process might use up the space while our system runs.) &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In each of these cases, the user should get appropriate feedback guiding her towards fixing the problem.&lt;br /&gt;
&lt;br /&gt;
Whenever the system tries to fix a parameter setup error by using some default set of parameters, it should do so only if&lt;br /&gt;
&lt;br /&gt;
*it presents the user with a warning that tells her what it did and why it did so, and if &lt;br /&gt;
&lt;br /&gt;
*the automatically fixed parameters are treated as if changed by the user, i.e. with a parameter check performed on them. &lt;br /&gt;
&lt;br /&gt;
Otherwise, people may unknowingly using a system that doesn&#039;t do what they want it to, or have&lt;br /&gt;
a system that creates new parameter inconsistencies when trying to fix others.&lt;br /&gt;
&lt;br /&gt;
====&#039;&#039;&#039;User Interface Details&#039;&#039;&#039;====&lt;br /&gt;
&lt;br /&gt;
The user interface for Parameter Setup Error handling is, along with the parameter setup dialog, part of the operator module. A first implementation of a GUI based user interface consists in a floating, non-modal error window popping up from the operator module that presents a list of error related textual messages to the user, allowing for browsing error messages&lt;br /&gt;
while changing respective parameters via the parameter setup dialog. After the next parameter check, the operator module will close that window or replace its contents based on the result of the check.&lt;br /&gt;
Parameter checking occurs when the user clicks the &amp;quot;SetConfig&amp;quot; button in the operator main window, followed by actually applying parameters if the check was successful.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===&#039;&#039;&#039;Runtime Errors&#039;&#039;&#039;===&lt;br /&gt;
&lt;br /&gt;
====&#039;&#039;&#039;Definition of the Term&#039;&#039;&#039;====&lt;br /&gt;
&lt;br /&gt;
This category covers everything that can go wrong in the course of running an application program, &lt;br /&gt;
insofar as that malfunction is due to a lack of resources in the underlying system required for proper operation (i.e., not due to a programming error). Assuming that parameter checking has been implemented properly as outlined above, we can narrow the term `Runtime Error&#039; to cases for which the following statement holds: A runtime error occurs whenever the system runs out of resources that were still available during parameter checking.&lt;br /&gt;
&lt;br /&gt;
Typical reasons for this kind of error are&lt;br /&gt;
  &lt;br /&gt;
*the system runs out of disk space while recording data, &lt;br /&gt;
&lt;br /&gt;
*files being moved, trashed, or locked by a concurrent process, &lt;br /&gt;
&lt;br /&gt;
*a network connection becomes unavailable. &lt;br /&gt;
&lt;br /&gt;
Runtime errors, when unhandled, become logic errors because the code implies assumptions that no longer hold once a runtime error has occurred.&lt;br /&gt;
&lt;br /&gt;
====&#039;&#039;&#039;Strategies&#039;&#039;&#039;====&lt;br /&gt;
&lt;br /&gt;
In a properly designed and implemented system, runtime errors, in the restricted sense described above, will not occur frequently. However, as they are caused by undesired circumstances outside the scope of the application program itself, it seems important to provide information to the user that is as detailed as possible in order to enable her to prevent this type of situation in the future, and to make her aware of the fact that the application program depends on her willingness to provide a smooth operating environment. That being said, it seems appropriate to simply abort execution altogether, while trying to avoid a loss of the data acquired up to that time.&lt;br /&gt;
&lt;br /&gt;
====&#039;&#039;&#039;User Interface Details&#039;&#039;&#039;====&lt;br /&gt;
&lt;br /&gt;
In general, it is desirable to have runtime errors displayed along with the user interface of the operator module. However, as this requires a working connection between the module where the error occurs, and the operator module, this may not always be possible. Therefore, in addition to an operator-based error reporting interface, each module should have a less demanding mechanism to provide error information to the user, e.g., a local log file.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===&#039;&#039;&#039;Logic Errors&#039;&#039;&#039;===&lt;br /&gt;
&lt;br /&gt;
====&#039;&#039;&#039;Definition of the Term&#039;&#039;&#039;====&lt;br /&gt;
&lt;br /&gt;
Logic, or programming, errors in general can be due to a programmer who, in his or her code, implicitly or explicitly makes assumptions that do not always hold.&lt;br /&gt;
&lt;br /&gt;
====&#039;&#039;&#039;Strategies&#039;&#039;&#039;====&lt;br /&gt;
&lt;br /&gt;
Programming errors are not supposed to occur at all in a tested version of an application. Therefore, instead of trying to &#039;handle&#039; them, it is important to make them show up as close to their point of origin in the code as possible, by frequently and explicitly checking whether&lt;br /&gt;
implicit assumptions actually hold, and aborting execution with an error message if this is not the case. &lt;br /&gt;
&lt;br /&gt;
Aside from that, writing code as explicit, general, and simple as possible greatly reduces the possibility of making logic errors in the first place.&lt;br /&gt;
&lt;br /&gt;
====&#039;&#039;&#039;User Interface Details&#039;&#039;&#039;====&lt;br /&gt;
&lt;br /&gt;
As programming errors are errors about which a user can do nothing, simply aborting the program or module with an error message seems appropriate.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==&#039;&#039;&#039;Implementation Details&#039;&#039;&#039;==&lt;br /&gt;
&lt;br /&gt;
===&#039;&#039;&#039;Interface to the Programmer&#039;&#039;&#039;===&lt;br /&gt;
&lt;br /&gt;
====&#039;&#039;&#039;Reporting Errors&#039;&#039;&#039;====&lt;br /&gt;
&lt;br /&gt;
For a simple and general way to provide user communication and a means of error reporting to a module&#039;s programmer, there exist two global objects derived from &amp;lt;tt&amp;gt;std::ostream&amp;lt;/tt&amp;gt;, one named&lt;br /&gt;
&amp;lt;tt&amp;gt;bciout&amp;lt;/tt&amp;gt; and the other named &amp;lt;tt&amp;gt;bcierr&amp;lt;/tt&amp;gt;, analogous to &amp;lt;tt&amp;gt;std::cout&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;std::cerr&amp;lt;/tt&amp;gt;, where &amp;lt;tt&amp;gt;bciout&amp;lt;/tt&amp;gt; is used to transfer general messages and warnings while &amp;lt;tt&amp;gt;bcierr&amp;lt;/tt&amp;gt; takes actual errors.&lt;br /&gt;
A code example then looks like this:&lt;br /&gt;
&lt;br /&gt;
  using namespace std;&lt;br /&gt;
  ...&lt;br /&gt;
  ofstream outputStream( fileName );&lt;br /&gt;
  if( !outputStream.is_open() )&lt;br /&gt;
  {&lt;br /&gt;
  bcierr &amp;lt;&amp;lt; &amp;quot;Cannot open the file \&amp;quot;&amp;quot;&lt;br /&gt;
         &amp;lt;&amp;lt; fileName&lt;br /&gt;
         &amp;lt;&amp;lt; &amp;quot;\&amp;quot; for output&amp;quot;&lt;br /&gt;
         &amp;lt;&amp;lt; endl;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
Furthermore, for handling runtime errors from which it is difficult to recover, a programmer may program an exception that will abort execution and eventually lead to an error message being sent to the operator module (for framework related details see the section entitled &amp;quot;Implementation on the Framework Side&amp;quot;):&lt;br /&gt;
&lt;br /&gt;
 ...&lt;br /&gt;
 if( ernie.find( bert ) != ernie.end() )&lt;br /&gt;
    throw &amp;quot;Ernie just ate Bert. &amp;quot; &lt;br /&gt;
              &amp;quot;I don&#039;t know how to tell the story.&amp;quot;;&lt;br /&gt;
 tellMyStory( bert.begin(), ernie.end() );&lt;br /&gt;
 ...&lt;br /&gt;
&lt;br /&gt;
====&#039;&#039;&#039;Checking Parameters&#039;&#039;&#039;====&lt;br /&gt;
&lt;br /&gt;
Checking parameters is done in a separate member function of the filter base class which, similar to the member function that does the actual processing, takes input and output signal representatives as parameters, thus allowing for signal property checking.&lt;br /&gt;
&lt;br /&gt;
For the actual implementation, its declaration is as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tt&amp;gt;void GenericFilter::Preflight ( const SignalProperties&amp;amp; inSignalProperties, SignalProperties&amp;amp; outSignalProperties ) const;&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For a filter class derived from &amp;lt;tt&amp;gt;GenericFilter&amp;lt;/tt&amp;gt;, this function is supposed to perform&lt;br /&gt;
parameter checking as described in the &amp;quot;Strategies&amp;quot; section. Instead of returning an error value, it writes possible error messages into &amp;lt;tt&amp;gt;bcierr&amp;lt;/tt&amp;gt;. Furthermore, it communicates dimensions of its output signal which it guarantees not to exceed, and it does so by adjusting the properties of the second SignalProperties object in its argument list, e.g.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tt&amp;gt;outSignalProperties&lt;br /&gt;
= SignalProperties( inSignalProperties.Channels(), 1 );&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
or&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tt&amp;gt;outSignalProperties = SignalProperties( 0, 0 );&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
if it declares not to use its output signal.&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;tt&amp;gt;const&amp;lt;/tt&amp;gt; declaration for its &amp;lt;tt&amp;gt;this&amp;lt;/tt&amp;gt; pointer prohibits initialization functionality from &amp;lt;tt&amp;gt;GenericFilter::Initialize()&amp;lt;/tt&amp;gt; entering into &amp;lt;tt&amp;gt;Preflight()&amp;lt;/tt&amp;gt;; this is unwanted because it would corrupt the idea of performing a &#039;&#039;complete&#039;&#039;  parameter check before actually &#039;&#039;altering&#039;&#039; the state of a filter object.&lt;br /&gt;
&lt;br /&gt;
A necessary condition for a correct implementation of the &amp;lt;tt&amp;gt;Preflight()&amp;lt;/tt&amp;gt; function is that any parameter, as well as any state that will be accessed during the processing phase, be accessed&lt;br /&gt;
from &amp;lt;tt&amp;gt;Preflight()&amp;lt;/tt&amp;gt; at least once. For parameters and states defined by the filter itself (i.e. inside its constructor), range and accessibility checks are automatically performed by the framework; parameters and states defined by other filters must be explicitly accessed from &amp;lt;tt&amp;gt;Preflight()&amp;lt;/tt&amp;gt;. If a &amp;lt;tt&amp;gt;GenericFilter&amp;lt;/tt&amp;gt; descendant fails to access an externally defined parameter or state during &amp;lt;tt&amp;gt;Preflight()&amp;lt;/tt&amp;gt;, the first access during the processing phase will result in a runtime error.&lt;br /&gt;
&lt;br /&gt;
====&#039;&#039;&#039;Accessing Environment Objects&#039;&#039;&#039;====&lt;br /&gt;
&lt;br /&gt;
We consider parameters and states part of the bci2000 &amp;quot;environment&amp;quot;. &amp;lt;tt&amp;gt;GenericFilter&amp;lt;/tt&amp;gt; descendants have access to that environment, analgous to the concept of environment variables found in some operating systems. Internally, access to the environment is mediated through a mix-in-class named &amp;lt;tt&amp;gt;Environment&amp;lt;/tt&amp;gt; that provides accessor symbols to a filter programmer.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Low Level Access to Environment Objects&#039;&#039;&#039; is provided by the following symbols:&lt;br /&gt;
  &lt;br /&gt;
*&amp;lt;tt&amp;gt;Parameters&amp;lt;/tt&amp;gt; syntactically behaves like a &amp;lt;tt&amp;gt;PARAMLIST*&amp;lt;/tt&amp;gt;, &lt;br /&gt;
&lt;br /&gt;
*&amp;lt;tt&amp;gt;States&amp;lt;/tt&amp;gt; behaves like a &amp;lt;tt&amp;gt;STATELIST*&amp;lt;/tt&amp;gt;, &lt;br /&gt;
&lt;br /&gt;
*and &amp;lt;tt&amp;gt;Statevector&amp;lt;/tt&amp;gt; behaves like a &amp;lt;tt&amp;gt;STATEVECTOR*&amp;lt;/tt&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
As an example, &lt;br /&gt;
&lt;br /&gt;
 float  myParameterValue = 0.0;&lt;br /&gt;
 PARAM* param = Parameters-&amp;gt;GetParamPtr( &amp;quot;MyParameter&amp;quot; );&lt;br /&gt;
 if( param )&lt;br /&gt;
 myParameterValue = atof( param-&amp;gt;GetValue() );&lt;br /&gt;
 else&lt;br /&gt;
 bcierr &amp;lt;&amp;lt; &amp;quot;Could not access \&amp;quot;MyParameter\&amp;quot;&amp;quot; &amp;lt;&amp;lt; endl;&lt;br /&gt;
&lt;br /&gt;
Unlike true pointers, these symbols cannot be assigned any values, cannot be assigned to variables, or have other manipulating operators applied. For example, the lines&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;tt&amp;gt;delete Parameters;&lt;br /&gt;
 Parameters = new PARAMLIST;&lt;br /&gt;
 PARAMLIST* someParamlistPointer = Parameters;&amp;lt;/tt&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
will all result in compiler errors. (In the current (preliminary) implementation, assignments from these symbols, as in the last example, are allowed to ease the transition process.)&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Convenient Access to Environment Objects&#039;&#039;&#039; is possible through a number of symbols which offer built-in checking and error reporting:&lt;br /&gt;
  &lt;br /&gt;
*{&amp;lt;tt&amp;gt;Parameter(Name[, Index 1[, Index 2]])&amp;lt;/tt&amp;gt;} &lt;br /&gt;
&lt;br /&gt;
This symbol stands for the value of the named parameter.  Indices may be given in numerical or textual form; if omitted, they default to 0. The type of the symbol &amp;lt;tt&amp;gt;Parameter()&amp;lt;/tt&amp;gt; may be numerical or a string type, depending on its use.(If the compiler complains about ambiguities, use explicit typecasts as in the second example.) If a parameter with the given name does not exist, an error message is written into &amp;lt;tt&amp;gt;bcierr&amp;lt;/tt&amp;gt;. If the specified indices do not exist, no error is reported. In both cases, on read access, the string constant &amp;lt;tt&amp;gt;&amp;quot;0&amp;quot;&amp;lt;/tt&amp;gt; resp. the number 0 is returned.&lt;br /&gt;
(If the compiler complains about ambiguities, use explicit typecasts as in the second example.)&lt;br /&gt;
&lt;br /&gt;
Examples: &lt;br /&gt;
&lt;br /&gt;
 &amp;lt;tt&amp;gt;int myValue = Parameter( &amp;quot;MyParam&amp;quot; ); &lt;br /&gt;
 string myOtherValue = ( const char* )Parameter( &amp;quot;MyOtherParam&amp;quot; ); &lt;br /&gt;
 Parameter( &amp;quot;My3rdParam&amp;quot;, 2, 3 ) = my3rdValue;&amp;lt;/tt&amp;gt;  &lt;br /&gt;
&lt;br /&gt;
*&amp;lt;tt&amp;gt;OptionalParameter(Default Value, Name[, Index 1[, Index 2]])&amp;lt;/tt&amp;gt; &lt;br /&gt;
&lt;br /&gt;
This symbol behaves like the symbol &amp;lt;tt&amp;gt;Parameter()&amp;lt;/tt&amp;gt; but will not report an error if the parameter does not exist. Instead, it will return the default value given in its first argument. Assignments to this symbol are not possible. &lt;br /&gt;
&lt;br /&gt;
*&amp;lt;tt&amp;gt;State(Name)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/tt&amp;gt; This symbol allows for reading a state&#039;s value from the state vector and setting a state&#039;s value in the state vector. Trying to access a state that is not accessible will result in an error reported via &amp;lt;tt&amp;gt;bcierr&amp;lt;/tt&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Examples:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;tt&amp;gt;short currentStateOfAffairs = State( &amp;quot;OfAffairs&amp;quot; ); &lt;br /&gt;
 State( &amp;quot;OfAffairs&amp;quot; ) = nextStateOfAffairs;&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*&amp;lt;tt&amp;gt;OptionalState(Default Value, Name)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/tt&amp;gt; Analagous to &amp;lt;tt&amp;gt;OptionalParameter()&amp;lt;/tt&amp;gt;, this symbol does not report an error if the specified state does not exist but returns the given default value. Assignments to this symbol are not possible. &lt;br /&gt;
&lt;br /&gt;
*&amp;lt;tt&amp;gt;PreflightCondition(Condition)&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This symbol is meant to be used inside implementations of  &amp;lt;tt&amp;gt;GenericFilter::Preflight()&amp;lt;/tt&amp;gt;. If the boolean condition given as its argument is false, it will output an error message into &amp;lt;tt&amp;gt;bcierr&amp;lt;/tt&amp;gt; containing the condition given in its argument. &lt;br /&gt;
&lt;br /&gt;
Example: &lt;br /&gt;
&lt;br /&gt;
&amp;lt;tt&amp;gt;PreflightCondition( Parameter( &amp;quot;TransmitCh&amp;quot; ) &amp;lt;= Parameter( &amp;quot;SourceCh&amp;quot; ) );&amp;lt;/tt&amp;gt; &lt;br /&gt;
&lt;br /&gt;
If TransmitCh is greater than SourceCh, a message will be sent to &amp;lt;tt&amp;gt;bcierr&amp;lt;/tt&amp;gt; and  displayed to the user, stating: &lt;br /&gt;
&lt;br /&gt;
&amp;lt;tt&amp;gt;Condition not fulfilled:   &lt;br /&gt;
Parameter( &amp;quot;TransmitCh&amp;quot; ) &amp;lt;= Parameter( &amp;quot;SourceCh&amp;quot; )&amp;lt;/tt&amp;gt; &lt;br /&gt;
&lt;br /&gt;
(In future versions, the error may be reported in natural language form generated from the boolean expression.)&lt;br /&gt;
 &lt;br /&gt;
===&#039;&#039;&#039;Implementation on the Framework Side&#039;&#039;&#039;===&lt;br /&gt;
&lt;br /&gt;
The behaviour of the operator module in response to an error message that arrives from one of the modules depends on its context, i.e., on the execution phase the system is in. That way, no additional programming interface elements visible to a filter/module programmer are needed to implement an error handling scheme as described in the &amp;quot;Handling Errors&amp;quot;section. &lt;br /&gt;
&lt;br /&gt;
During the &#039;&#039;&#039;preflight phase,&#039;&#039;&#039;  errors are {Parameter Setup Errors}. A module&#039;s framework code behind &amp;lt;tt&amp;gt;bcierr&amp;lt;/tt&amp;gt; just collects error messages; on return from the preflight function, it&lt;br /&gt;
sends those messages to the operator module which then, from the contents of the message (i.e., whether it was empty or not), determines whether the preflight was successful; on not receiving any message after some timeout it assumes a broken connection or a crashed module.&lt;br /&gt;
&lt;br /&gt;
(For now, a simple timeout scheme with a fixed timeout interval of 5s seems appropriate. In the future, one might consider a module requesting additional timeout periods if it expects lengthy calculations.)&lt;br /&gt;
&lt;br /&gt;
During all &#039;&#039;&#039;other phases,&#039;&#039;&#039;  the code behind &amp;lt;tt&amp;gt;bcierr&amp;lt;/tt&amp;gt; immediately (i.e., on flushing the &amp;lt;tt&amp;gt;std::ostream&amp;lt;/tt&amp;gt;) sends its message buffer to a log file as well as to the operator module, indicating a {Runtime Error} to the operator module which will, in turn, halt the system,shut down the other modules, and display the message to the user.&lt;br /&gt;
&lt;br /&gt;
In addition, the top level exception handling code of each module contains similar functionality,&lt;br /&gt;
sending an exception&#039;s associated description string into a log file and to the operator module, if possible, then quitting the module in which the exception occurred. This not only ensures&lt;br /&gt;
a proper general handling of exceptions within the framework but also allows a programmer to handle {Runtime Errors} by raising her own exceptions, eliminating the need to take care of the error&lt;br /&gt;
condition in the code following the detection of an error.&lt;/div&gt;</summary>
		<author><name>Atennissen</name></author>
	</entry>
	<entry>
		<id>https://www.bci2000.org/mediawiki/index.php?title=Programming_Reference:Debug_Output&amp;diff=1761</id>
		<title>Programming Reference:Debug Output</title>
		<link rel="alternate" type="text/html" href="https://www.bci2000.org/mediawiki/index.php?title=Programming_Reference:Debug_Output&amp;diff=1761"/>
		<updated>2007-05-08T19:58:16Z</updated>

		<summary type="html">&lt;p&gt;Atennissen: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;When writing your own BCI2000 module, you will sometimes want to report values of variables, execution of a certain function, or other information that is &lt;br /&gt;
*irrelevant to the user, but&lt;br /&gt;
*helps you check whether your code does what it is supposed to.&lt;br /&gt;
&lt;br /&gt;
Often, programmers use individual log files for debugging output, and review those files while their program runs, or afterwards.&lt;br /&gt;
&lt;br /&gt;
This page describes how the BCI2000 C++ framework allows you to easily display debugging information in the operator module&#039;s log window, without bothering about creating your own log file.&lt;br /&gt;
Nevertheless, you are free to use your own log file if you feel that this better fits your needs.&lt;br /&gt;
&lt;br /&gt;
==Debugging Stream &amp;lt;tt&amp;gt;bcidbg&amp;lt;/tt&amp;gt;==&lt;br /&gt;
Similar to the &amp;lt;tt&amp;gt;bcierr&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;bciout&amp;lt;/tt&amp;gt; streams used for error handling and user warnings, BCI2000 provides a &amp;lt;tt&amp;gt;std::ostream&amp;lt;/tt&amp;gt; derived object that accepts strings and numbers for formatted output.&lt;br /&gt;
Like the output of &amp;lt;tt&amp;gt;bcierr&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;bciout&amp;lt;/tt&amp;gt;, data from &amp;lt;tt&amp;gt;bcidbg&amp;lt;/tt&amp;gt; is directed into the operator module&#039;s log window.&lt;br /&gt;
Similar to error and warning messages, debugging messages will be time stamped and provided with a function context.&lt;br /&gt;
&lt;br /&gt;
However, there are important differences:&lt;br /&gt;
*Unlike for &amp;lt;tt&amp;gt;bcierr&amp;lt;/tt&amp;gt;, the framework does not interpret the fact that something was written to the stream.&lt;br /&gt;
*&amp;lt;tt&amp;gt;bcidbg&amp;lt;/tt&amp;gt; can conditionally &#039;&#039;&#039;ignore&#039;&#039;&#039; the data inserted into it, according to a user-defined global setting. That way, you need not remove your debugging code, nor devise your own conditional output scheme.&lt;br /&gt;
*Messages are formatted unobtrusively, and will not automatically pop up the window.&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;tt&amp;gt;bcidbg&amp;lt;/tt&amp;gt; stream is available globally, and used as any other &amp;lt;tt&amp;gt;std::ostream&amp;lt;/tt&amp;gt; descendant:&lt;br /&gt;
 mSomeDataMember = SomeFunction();&lt;br /&gt;
 bcidbg &amp;lt;&amp;lt; &amp;quot;Set mSomeDataMember to &amp;quot; &amp;lt;&amp;lt; mSomeDataMember &amp;lt;&amp;lt; endl;&lt;br /&gt;
&lt;br /&gt;
Note that, just as for &amp;lt;tt&amp;gt;bcierr&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;bciout&amp;lt;/tt&amp;gt;, writing to &amp;lt;tt&amp;gt;bcidbg&amp;lt;/tt&amp;gt; will not take effect unless it is flushed by inserting &amp;lt;tt&amp;gt;flush&amp;lt;/tt&amp;gt; or &amp;lt;tt&amp;gt;endl&amp;lt;/tt&amp;gt;. (The latter will insert a newline character before flushing the stream.)&lt;br /&gt;
&lt;br /&gt;
==The Debug Level==&lt;br /&gt;
A &#039;&#039;Debug Level&#039;&#039; concept is used to control the output of debug messages.&lt;br /&gt;
Basically, a user-specified debug level is compared to the debug levels of individual messages,  and messages with a debug level &#039;&#039;above&#039;&#039; the user-specified debug level will be &#039;&#039;suppressed&#039;&#039; from the output. As the debug level defaults to 0, no debug messages will be visible to an end user unless configured accordingly.&lt;br /&gt;
&lt;br /&gt;
Individual messages are associated with a numerical value, their &#039;&#039;Debug Level&#039;&#039;, roughly correlating with their significance. Important and sparse messages are given a low debug level value, less important and probably more frequent messages are given a higher debug level.&lt;br /&gt;
&lt;br /&gt;
===Message Debug Level===&lt;br /&gt;
The default message debug level is 1.&lt;br /&gt;
 bcidbg &amp;lt;&amp;lt; &amp;quot;This is an important message on any level of debugging&amp;quot; &amp;lt;&amp;lt; endl;&lt;br /&gt;
To give a message a higher debug level, put it in brackets after the &amp;lt;tt&amp;gt;bcidbg&amp;lt;/tt&amp;gt; name:&lt;br /&gt;
 bcidbg( 10 ) &amp;lt;&amp;lt; &amp;quot;This is a fairly uninteresting message&amp;quot; &amp;lt;&amp;lt; endl;&lt;br /&gt;
Although there is practically no upper limit to debug level values, &lt;br /&gt;
a usual range for debug levels is from 1 to 10.&lt;br /&gt;
&lt;br /&gt;
===Global Debug Level===&lt;br /&gt;
The amount of actual debugging output is governed by a global debug level.&lt;br /&gt;
In BCI2000, this value is corresponds to the &#039;&#039;&#039;DebugLevel&#039;&#039;&#039; parameter. This parameter is not normally available, and must be specified from the command line when starting a module:&lt;br /&gt;
 FeedbackDemo 127.0.0.1 --DebugLevel=10&lt;br /&gt;
will start the FeedbackDemo module with a quite verbose debug level of 10.&lt;br /&gt;
Note that the debug level parameter will propagate to the other modules only after &amp;quot;Set Config&amp;quot; has been pressed from the operator module. Thus, other modules must be started with the DebugLevel argument, as well, if you need to view debugging messages from operation phases prior to the Initialization Phase.&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
See also: [[Error Streams]]|[[States of Operation]]&lt;/div&gt;</summary>
		<author><name>Atennissen</name></author>
	</entry>
	<entry>
		<id>https://www.bci2000.org/mediawiki/index.php?title=Technical_Reference:App_Connector&amp;diff=1760</id>
		<title>Technical Reference:App Connector</title>
		<link rel="alternate" type="text/html" href="https://www.bci2000.org/mediawiki/index.php?title=Technical_Reference:App_Connector&amp;diff=1760"/>
		<updated>2007-05-08T19:37:18Z</updated>

		<summary type="html">&lt;p&gt;Atennissen: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Introduction==&lt;br /&gt;
The BCI2000 external application interface provides a bi-directional link to exchange &lt;br /&gt;
information with external processes running on the same machine, or on a different machine&lt;br /&gt;
over a local network.&lt;br /&gt;
Via the external application interface, read/write access to BCI2000 [[state vector]] information and [[control signal]]s is possible. An external application may &lt;br /&gt;
read the &amp;lt;tt&amp;gt;ResultCode&amp;lt;/tt&amp;gt; state to access the classification result, set the &lt;br /&gt;
&amp;lt;tt&amp;gt;TargetCode&amp;lt;/tt&amp;gt; state to control the user&#039;s task, or get access to the &lt;br /&gt;
control signal that is calculated by SignalProcessing so as to control an &lt;br /&gt;
external output device (such as a robotic arm or a web browser). Multiple &lt;br /&gt;
instances of BCI2000 running on separate machines may share sequencing and &lt;br /&gt;
control signal information, allowing for interactive applications such as games.&lt;br /&gt;
&lt;br /&gt;
===Scope===&lt;br /&gt;
The scope of this interface is to provide access to internal BCI2000 information &lt;br /&gt;
for cases in which the generation of a full-fledged [[BCI2000 module]] is &lt;br /&gt;
impractical. Such a case might be the control of external applications that &lt;br /&gt;
practically do not allow full incorporation into the BCI2000 framework (such as &lt;br /&gt;
the Dasher system for efficient low-bandwidth spelling). &lt;br /&gt;
&lt;br /&gt;
This interface is &lt;br /&gt;
&#039;&#039;NOT&#039;&#039;  intended to replace the existing BCI2000 framework for BCI2000 &lt;br /&gt;
communication. The advantages of writing modules that are fully integrated into &lt;br /&gt;
the BCI2000 framework are that their configuration is achieved through the same &lt;br /&gt;
interface as other BCI2000 configuration, that this configuration is stored in &lt;br /&gt;
the data file along with all other system parameters, and that the state of the &lt;br /&gt;
module at any given time is encoded in event markers that are also stored in the &lt;br /&gt;
data file. In contrast, control of an external device using the External &lt;br /&gt;
Application Interface implies that the configuration of the external device has &lt;br /&gt;
to be done outside of BCI2000, that this corresponding configuration is not &lt;br /&gt;
stored along with the data file, and that the internal state of the output &lt;br /&gt;
device is not saved together with the brain signals. This will make it more &lt;br /&gt;
difficult to reconstruct what exactly was going on during an experimental &lt;br /&gt;
session. It is thus important to keep this in mind when using this &lt;br /&gt;
possibility.&lt;br /&gt;
&lt;br /&gt;
===Design===&lt;br /&gt;
The design of the external application interface aims at simplicity, and at minimal &lt;br /&gt;
interference with the timing of the signal flow through the BCI2000 system. With &lt;br /&gt;
this in mind, a connection-less, UDP based transmission protocol was chosen &lt;br /&gt;
rather than one based on TCP. This comes at the cost of a possible loss, or &lt;br /&gt;
reordering of protocol messages. To keep the probability for such losses as low &lt;br /&gt;
as possible, and their consequences as local as possible, messages have been &lt;br /&gt;
designed to be short, self-contained, and redundantly encoded in a human &lt;br /&gt;
readable fashion.&lt;br /&gt;
&lt;br /&gt;
The connectionless nature of UDP implies that there is no &#039;&#039;server&#039;&#039; or &#039;&#039;client&#039;&#039; in the asymmetric sense that applies for TCP connections. Rather, processes write to local or remote UDP ports, and read from local UDP ports, whenever applicable.&lt;br /&gt;
Thus, for bi-directional communication between machine A running BCI2000 and machine B running the external application, there will be two UDP ports involved:&lt;br /&gt;
* a port on machine B into which BCI2000 writes out its messages to the external application, and&lt;br /&gt;
* a port on machine A into which the external application writes its messages to BCI2000.&lt;br /&gt;
In most cases, both BCI2000 and the external application will run on the same machine, i.e., A and B will refer to the same machine, and both ports will be local. Still, they are distinct ports.&lt;br /&gt;
&lt;br /&gt;
For communication involving a large number of network nodes, or unreliable connections, we suggest &lt;br /&gt;
using local UDP communication, in conjunction with locally executed TCP/IP server processes that forward messages to a TCP connection between the two remote machines.&lt;br /&gt;
&lt;br /&gt;
==Description==&lt;br /&gt;
For each block of data processed by the BCI2000 system, two types of information are sent out&lt;br /&gt;
and may be received from the external application interface:&lt;br /&gt;
*the BCI2000 internal state as defined by the values of the entries of its state vector data structure, and &lt;br /&gt;
*the BCI2000 control signals.&lt;br /&gt;
 &lt;br /&gt;
For the definition of and details about states and the control signal, please refer to the BCI2000&lt;br /&gt;
project outline document.&lt;br /&gt;
Sending data occurs immediately after the task filter of the application module processes the data; &lt;br /&gt;
receiving occurs immediately before the task filter.&lt;br /&gt;
This ensures that changes resulting from user choices are sent out immediately, and that &lt;br /&gt;
received information will immediately be available to the task filter.&lt;br /&gt;
IP addresses and ports used are user-configurable. Sending and receiving need not use the same address and port.&lt;br /&gt;
&lt;br /&gt;
==Protocol==&lt;br /&gt;
Messages consist of a name and a value, separated by white space&lt;br /&gt;
and terminated with a single newline (&amp;lt;code&amp;gt;&#039;\n&#039;==0x0a&amp;lt;/code&amp;gt;) character.&lt;br /&gt;
Names may identify&lt;br /&gt;
*BCI2000 states by name -- then followed by an integer value in decimal ASCII representation;&lt;br /&gt;
*Signal elements in the form &amp;lt;tt&amp;gt;Signal(&amp;lt;channel&amp;gt;,&amp;lt;element&amp;gt;)&amp;lt;/tt&amp;gt; -- then followed by a float value in decimal ASCII representation.&lt;br /&gt;
 &lt;br /&gt;
==Examples==&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Running 0\n&lt;br /&gt;
ResultCode 2\n&lt;br /&gt;
Signal(1,2) 1e-8\n&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Note that the first example will switch BCI2000 into a suspended state.&lt;br /&gt;
While the system is in that state, no communication is possible over the application protocol.&lt;br /&gt;
&lt;br /&gt;
==Parameterization from within BCI2000==&lt;br /&gt;
BCI2000 reads data from a local IP socket specified by the &lt;br /&gt;
&amp;lt;tt&amp;gt;ConnectorInputAddress&amp;lt;/tt&amp;gt; parameter, and writes data out into the socket specified by the &lt;br /&gt;
&amp;lt;tt&amp;gt;ConnectorOutputAddress&amp;lt;/tt&amp;gt; parameter.&lt;br /&gt;
Sockets are specified by an address/port combination.&lt;br /&gt;
Addresses may be host names, or numerical IP addresses. Address and port are separated by&lt;br /&gt;
a colon as in&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
localhost:5000&lt;br /&gt;
134.2.103.151:20321&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
For incoming values, messages are filtered by name using a list of allowed names &lt;br /&gt;
present in the &amp;lt;tt&amp;gt;ConnectorInputFilter&amp;lt;/tt&amp;gt; parameter. &lt;br /&gt;
To allow signal messages, allowed signal elements must be specified including their&lt;br /&gt;
indices.&lt;br /&gt;
To allow all names, enter an asterisk (*) as the only list entry.&lt;br /&gt;
&lt;br /&gt;
==Examples==&lt;br /&gt;
===BCI2000 example code===&lt;br /&gt;
* A simple few-line program that uses AppConnector information from BCI2000 to control the state of the parallel port is found at [http://{{SERVERNAME}}/tracproj/browser/trunk/src/AppConnectorApplications/ParallelSwitch/ParallelSwitch.cpp BCI2000/src/AppConnectorApplications/ParallelSwitch/].&lt;br /&gt;
* A GUI application that allows to interactively play with BCI2000 states is found at [http://{{SERVERNAME}}/tracproj/browser/trunk/src/AppConnectorApplications/AppConnectorExample BCI2000/src/AppConnectorApplications/AppConnectorExample] (a compiled executable is [http://{{SERVERNAME}}/tracproj/browser/trunk/tools/AppConnectorExample here]).&lt;br /&gt;
* A minimum C++ program forwarding BCI2000 AppConnector messages to stdout (using the BCI2000 &amp;lt;code&amp;gt;TCPStream&amp;lt;/code&amp;gt; class) reads&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;iostream&amp;gt;&lt;br /&gt;
#include &amp;quot;SockStream.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
using namespace std;&lt;br /&gt;
&lt;br /&gt;
int main( int argc, char** argv )&lt;br /&gt;
{&lt;br /&gt;
  const char* address = &amp;quot;localhost:5000&amp;quot;;&lt;br /&gt;
  if( argc &amp;gt; 1 )&lt;br /&gt;
    address = argv[ 1 ];&lt;br /&gt;
&lt;br /&gt;
  receiving_udpsocket socket( address );&lt;br /&gt;
  sockstream connection( socket );&lt;br /&gt;
  string line;&lt;br /&gt;
  // Print each line of BCI2000 input to stdout.&lt;br /&gt;
  while( getline( connection, line ) )&lt;br /&gt;
    cout &amp;lt;&amp;lt; line &amp;lt;&amp;lt; endl;&lt;br /&gt;
&lt;br /&gt;
  return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===An external application reading information from BCI2000, running locally===&lt;br /&gt;
* Set the &amp;lt;tt&amp;gt;ConnectorOutputAddress&amp;lt;/tt&amp;gt; parameter to a local address above 1024, such as &amp;lt;code&amp;gt;localhost:5000&amp;lt;/code&amp;gt;.&lt;br /&gt;
* In the external application, create a UDP socket and bind it to BCI2000&#039;s output port, i.e. &amp;lt;code&amp;gt;localhost:5000&amp;lt;/code&amp;gt;. &lt;br /&gt;
* Read from that socket as you would from a TCP socket.&lt;br /&gt;
===An external application reading information from BCI2000, running on a remote machine===&lt;br /&gt;
* Set the &amp;lt;tt&amp;gt;ConnectorOutputAddress&amp;lt;/tt&amp;gt; parameter to a remote address above 1024, such as &amp;lt;code&amp;gt;134.2.102.151:20321&amp;lt;/code&amp;gt;.&lt;br /&gt;
* In the external program, create a UDP socket, and bind it to the remote machine&#039;s external address, i.e. &amp;lt;code&amp;gt;134.2.102.151:20321&amp;lt;/code&amp;gt; rather than &amp;lt;code&amp;gt;localhost:20321&amp;lt;/code&amp;gt;.&lt;br /&gt;
* Read from that socket as you would from a TCP socket.&lt;br /&gt;
===An external application sending information to BCI2000, running locally===&lt;br /&gt;
* Set the &amp;lt;tt&amp;gt;ConnectorInputAddress&amp;lt;/tt&amp;gt; parameter to a local address above 1024, such as &amp;lt;code&amp;gt;localhost:5001&amp;lt;/code&amp;gt;.&lt;br /&gt;
* Set the &amp;lt;tt&amp;gt;ConnectorInputFilter&amp;lt;/tt&amp;gt; to &amp;lt;code&amp;gt;*&amp;lt;/code&amp;gt; (a single asterisk).&lt;br /&gt;
* In the external application, create a UDP socket and bind it to BCI2000&#039;s input port, i.e. &amp;lt;code&amp;gt;localhost:5001&amp;lt;/code&amp;gt;.&lt;br /&gt;
* Write to that socket whenever appropriate, without waiting for a connection to be established.&lt;br /&gt;
===An external application sending information to BCI2000, running on a remote machine===&lt;br /&gt;
* Set the &amp;lt;tt&amp;gt;ConnectorInputAddress&amp;lt;/tt&amp;gt; parameter to the local machine&#039;s external address, and a port above 1024, such as &amp;lt;code&amp;gt;bci2000machine.yourdomain.org:20320&amp;lt;/code&amp;gt;.&lt;br /&gt;
* In the external program, create a UDP socket and bind it to the BCI2000 machine&#039;s external address, i.e. &amp;lt;code&amp;gt;bci2000machine.yourdomain.org:20320&amp;lt;/code&amp;gt;.&lt;br /&gt;
* Write to that socket whenever appropriate, without waiting for a connection to be established.&lt;/div&gt;</summary>
		<author><name>Atennissen</name></author>
	</entry>
	<entry>
		<id>https://www.bci2000.org/mediawiki/index.php?title=User_Reference:SpatialFilter&amp;diff=1759</id>
		<title>User Reference:SpatialFilter</title>
		<link rel="alternate" type="text/html" href="https://www.bci2000.org/mediawiki/index.php?title=User_Reference:SpatialFilter&amp;diff=1759"/>
		<updated>2007-05-08T17:57:46Z</updated>

		<summary type="html">&lt;p&gt;Atennissen: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Function==&lt;br /&gt;
The SpatialFilter computes an instantaneous linear transformation of its input.&lt;br /&gt;
This linear transformation is described by a transformation matrix, and applied for each sample separately, not linking data across different points in time.&lt;br /&gt;
&lt;br /&gt;
Typically, the SpatialFilter&#039;s input is the unfiltered brain signal from the source module.&lt;br /&gt;
&lt;br /&gt;
==Parameters==&lt;br /&gt;
[[Image:SpatialFilter.png|right|256px]]&lt;br /&gt;
&#039;&#039;SpatialFilter&#039;&#039; is a matrix defining the linear transformation applied to the filter&#039;s input signal.&lt;br /&gt;
In this matrix, columns represent input channels, and rows represent output channels.&lt;br /&gt;
Each matrix element defines a weight with which the respective input channel (column) enters into the respective output channel (row).&lt;br /&gt;
&lt;br /&gt;
If the spatial filter is an identity filter -- not modifying its input --, then the SpatialFilter matrix is a unit matrix (square matrix with ones on the main diagonal, and all other elements zero).&lt;br /&gt;
&lt;br /&gt;
In a typical EEG experiment with fixed montage, you might want column labels to reflect the respective electrode location, simplifying the task of further modifications to the spatial filter.&lt;br /&gt;
&lt;br /&gt;
==States==&lt;br /&gt;
None.&lt;br /&gt;
&lt;br /&gt;
==Examples==&lt;br /&gt;
===Linked Mastoids===&lt;br /&gt;
Physical reference is to the left mastoid (A1). The right mastoid (A2) is recorded vs A1 on channel 1. All other electrodes are recorded vs A1 as well, and use the remaining channels.&lt;br /&gt;
In your spatial filter, you will want to re-reference all channels against &amp;quot;linked mastoids&amp;quot;, i.e. against the mean of A1 and A2.&lt;br /&gt;
&lt;br /&gt;
In the spatial filter matrix, you want to subtract half of the A2 channel from each of the remaining channels:&lt;br /&gt;
{| border=&amp;quot;1&amp;quot; cellspacing=&amp;quot;0&amp;quot; style=&amp;quot;text-align:center&amp;quot;&lt;br /&gt;
|+ Linked Mastoids&lt;br /&gt;
! &amp;amp;nbsp; !! A2  !! Fz !! Cz !! Pz !! ...&lt;br /&gt;
|-&lt;br /&gt;
! Fz&#039;&lt;br /&gt;
| -1/2 ||  1 ||  0 ||  0 || rowspan=&amp;quot;3&amp;quot; | ...&lt;br /&gt;
|-&lt;br /&gt;
! Cz&#039;&lt;br /&gt;
| -1/2 ||  0 ||  1 ||  0&lt;br /&gt;
|-&lt;br /&gt;
! Pz&#039;&lt;br /&gt;
| -1/2 ||  0 ||  0 ||  1&lt;br /&gt;
|-&lt;br /&gt;
| &amp;amp;nbsp; || colspan=&amp;quot;5&amp;quot; | ...&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===Common Average Reference===&lt;br /&gt;
Signals are to be re-referenced against the average of all channels.&lt;br /&gt;
To achieve this, begin with an identity matrix, and subtract a matrix of all ones, divided by the number &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; of input channels:&lt;br /&gt;
{| border=&amp;quot;1&amp;quot; cellspacing=&amp;quot;0&amp;quot; style=&amp;quot;text-align:center&amp;quot;&lt;br /&gt;
|+ Common Average Reference&lt;br /&gt;
! &amp;amp;nbsp; !! Fz !! Cz !! Pz !! Oz !! ...&lt;br /&gt;
|-&lt;br /&gt;
! Fz&#039;&lt;br /&gt;
| 1-1/N || 1/N || 1/N || 1/N || rowspan=&amp;quot;4&amp;quot; | ...&lt;br /&gt;
|-&lt;br /&gt;
! Cz&#039;&lt;br /&gt;
| 1/N ||  1-1/N || 1/N || 1/N &lt;br /&gt;
|-&lt;br /&gt;
! Pz&#039;&lt;br /&gt;
| 1/N || 1/N || 1-1/N || 1/N &lt;br /&gt;
|-&lt;br /&gt;
! Oz&#039;&lt;br /&gt;
| 1/N || 1/N || 1/N || 1-1/N&lt;br /&gt;
|-&lt;br /&gt;
| &amp;amp;nbsp; || colspan=&amp;quot;5&amp;quot; | ...&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Atennissen</name></author>
	</entry>
	<entry>
		<id>https://www.bci2000.org/mediawiki/index.php?title=User_Reference:Filters&amp;diff=1758</id>
		<title>User Reference:Filters</title>
		<link rel="alternate" type="text/html" href="https://www.bci2000.org/mediawiki/index.php?title=User_Reference:Filters&amp;diff=1758"/>
		<updated>2007-05-08T17:53:27Z</updated>

		<summary type="html">&lt;p&gt;Atennissen: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&#039;&#039;Filters&#039;&#039; are the most important building blocks of a BCI2000 system.&lt;br /&gt;
This document describes the &#039;&#039;filter&#039;&#039; concept for users who will configure BCI2000 for their own experiments, and provides links to the documentation pages of individual filters, describing each filter&#039;s purpose and parameterization.&lt;br /&gt;
&lt;br /&gt;
==Data Processing as a Pipe==&lt;br /&gt;
Each of the three BCI2000 core modules contains a &#039;&#039;chain of filters&#039;&#039;, i.e. a sequence of filters forming a pipe where, basically, brain signal data enter on one side, and a processed version of these data leaves on the other side.&lt;br /&gt;
&lt;br /&gt;
The notion of a &#039;&#039;pipe&#039;&#039; implies that, for each portion of data entering on the input side, there will be exactly one portion of output data on the output side.&lt;br /&gt;
This is analogous to a water pipe: unlike a water stream (a brook, or a river), it is impossible to insert or remove water from inside the pipe without breaking it.&lt;br /&gt;
Similarly, albeit signal portions may change their shape on their way through the pipe (filter chain), it is impossible to insert or remove any of them.&lt;br /&gt;
Thus, each data portion acquired by the data acquisition module will run through the entire BCI2000 system, being processed by a sequence of filters.&lt;br /&gt;
&lt;br /&gt;
==Configuration Overview==&lt;br /&gt;
In principle, these filters may be placed in any order by the writer (programmer) of a BCI2000 module, and it is [[Programming Reference:Filter Chain|technically easy]] to change the number, and order, of filters. &lt;br /&gt;
However, not all combinations or orderings of filters make sense.&lt;br /&gt;
&lt;br /&gt;
The table shows modules and filters for BCI2000 configurations included in the core distribution:&lt;br /&gt;
&lt;br /&gt;
{| border=&amp;quot;1&amp;quot; style=&amp;quot;text-align:center&amp;quot;&lt;br /&gt;
! colspan=&amp;quot;3&amp;quot; | Data Acquisition &lt;br /&gt;
! colspan=&amp;quot;4&amp;quot; | Signal Processing &lt;br /&gt;
! colspan=&amp;quot;3&amp;quot; | Application&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; |&lt;br /&gt;
{| border=&amp;quot;0&amp;quot; style=&amp;quot;text-align:center&amp;quot; &lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | DataIOFilter &lt;br /&gt;
|-&lt;br /&gt;
| ADC || FileWriter&lt;br /&gt;
|} &lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | AlignmentFilter &lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | TransmissionFilter&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | SpatialFilter&lt;br /&gt;
| ARFilter || rowspan=&amp;quot;2&amp;quot; | LinearClassifier || rowspan=&amp;quot;2&amp;quot; | Normalizer&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | ConnectorInput &lt;br /&gt;
| CursorTask &lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | ConnectorOutput&lt;br /&gt;
|-&lt;br /&gt;
| P3TemporalFilter&lt;br /&gt;
| P3AVTask, P3SpellerTask&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==Data Acquisition Module==&lt;br /&gt;
In the data acquisition (source) module, the DataIOFilter manages data acquisition and storage in a general manner.&lt;br /&gt;
Actual acquisition of data is provided by ADC filters,&lt;br /&gt;
actual writing into data files is done by FileWriter filters representing various [[Data Formats]].&lt;br /&gt;
In addition to managing the operation of ADC and FileWriter filters, the DataIOFilter handles signal calibration into physical units (generally, &amp;lt;math&amp;gt;\mu V&amp;lt;/math&amp;gt;), and visualization of the source signal.&lt;br /&gt;
&lt;br /&gt;
Filter documentation for source modules is available for&lt;br /&gt;
===General Filters===&lt;br /&gt;
*[[User Reference:DataIOFilter]]: Storage and acquisition management, calibration.&lt;br /&gt;
*[[User Reference:AlignmentFilter]]: Temporal alignment.&lt;br /&gt;
*[[User Reference:TransmissionFilter]]: Subset selection for online processing.&lt;br /&gt;
===ADC Filters===&lt;br /&gt;
*[[User Reference:RandomNumberADC]]: A random signal generator for testing purposes.&lt;br /&gt;
*[[User Reference:gUSBampADC]]: Interface to the g.tec gUSBamp amplifier.&lt;br /&gt;
*[[User Reference:gMOBIlabADC]]: Interface to the g.tec gMOBIlab amplifier.&lt;br /&gt;
*[[User Reference:DAS_ADC]]: Interface to MeasurementComputing AD cards.&lt;br /&gt;
*[[User Reference:DTADC]]: Interface to Data Translation boards.&lt;br /&gt;
*[[User Reference:NIADC]]: Interface to National Instruments boards.&lt;br /&gt;
*[[User Reference:NeuroscanADC]]: Neuroscan Acquire socket protocol client.&lt;br /&gt;
*[[User Reference:RDAClientADC]]: Brain Vision RDA socket protocol client.&lt;br /&gt;
*[[Contributions:ADCs]]: Contributed code interfacing to other hardware.&lt;br /&gt;
===FileWriter Filters===&lt;br /&gt;
*[[User Reference:BCI2000FileWriter]]: BCI2000 data format.&lt;br /&gt;
*[[User Reference:EDFFileWriter]]: European Data Format.&lt;br /&gt;
*[[User Reference:GDFFileWriter]]: General Data Format for Biosignals.&lt;br /&gt;
*[[User Reference:NullFileWriter]]: Suppressing file output.&lt;br /&gt;
*[[Contributions:FileWriters]]: Contributed code supporting other output formats.&lt;br /&gt;
&lt;br /&gt;
==Signal Processing Module==&lt;br /&gt;
In the signal processing module, brain signals are filtered spatially and temporally, resulting in a set of extracted features. In the Classifier, these features are used to differentiate amongst a small number of mental states (classes). Finally, the Normalizer adjusts the Classifier&#039;s output to zero mean and unit variance.&lt;br /&gt;
&lt;br /&gt;
Filter documentation for signal processing filters is available for&lt;br /&gt;
===General Filters===&lt;br /&gt;
*[[User Reference:SpatialFilter]]: Instantaneous (i.e., sample-wise) linear transformation of brain signal input.&lt;br /&gt;
*[[User Reference:LinearClassifier]]: Linear projection of signal features onto low-dimensional classification space (control signal).&lt;br /&gt;
*[[User Reference:Normalizer]]: Adjustment of control signal to zero mean/unit variance.&lt;br /&gt;
*[[User Reference:LowPassFilter]]: Temporal low-pass filtering at any stage of processing.&lt;br /&gt;
===Specific Filters===&lt;br /&gt;
*[[User Reference:ARFilter]]: Auto-regression based spectral amplitude estimator.&lt;br /&gt;
*[[User Reference:FFTFilter]]: Short-term FFT for display or feature extraction purposes.&lt;br /&gt;
*[[User Reference:P3TemporalFilter]]: Segmenting and averaging for ERP feature extraction.&lt;br /&gt;
===Offline Processing===&lt;br /&gt;
*[[User Reference:ConditionalIntegrator]]: An offline replacement for cursor movement in an online task.&lt;br /&gt;
*[[User Reference:StateTransform]]: An offline replacement for hitting targets in an online task.&lt;br /&gt;
&lt;br /&gt;
==Application Module==&lt;br /&gt;
Basically, the application module contains a single filter that handles trial sequencing and brain signal feedback.&lt;br /&gt;
In the standard configuration, this &#039;&#039;task&#039;&#039; filter is surrounded by ConnectorInput and ConnectorOutput filters. These connector filters allow for exchanging data with external software over a UDP based socket protocol.&lt;br /&gt;
&lt;br /&gt;
Filter documentation of application module filters is available for&lt;br /&gt;
===Stimulus Presentation and Feedback===&lt;br /&gt;
*[[User Reference:CursorTask]]: Feedback of brain signals in form of up to 3-dimensional cursor movement.&lt;br /&gt;
*[[User Reference:P3AVTask]]: Sequential presentation of stimuli.&lt;br /&gt;
*[[User Reference:P3Speller]]: A P300 speller matrix application.&lt;br /&gt;
===External Interfacing Filters===&lt;br /&gt;
*[[User Reference:ConnectorOutput]]: Reports state information to a UDP socket.&lt;br /&gt;
*[[User Reference:ConnectorInput]]: Sets state information according to input from a UDP socket.&lt;br /&gt;
*[[UserReference:KeystrokeFilter]]: Translates state information into simulated keyboard input.&lt;br /&gt;
===Internationalization===&lt;br /&gt;
*[[User Reference:Localization]]: Translating subject-visible messages.&lt;/div&gt;</summary>
		<author><name>Atennissen</name></author>
	</entry>
	<entry>
		<id>https://www.bci2000.org/mediawiki/index.php?title=Technical_Reference:States_of_Operation&amp;diff=1757</id>
		<title>Technical Reference:States of Operation</title>
		<link rel="alternate" type="text/html" href="https://www.bci2000.org/mediawiki/index.php?title=Technical_Reference:States_of_Operation&amp;diff=1757"/>
		<updated>2007-05-08T17:44:39Z</updated>

		<summary type="html">&lt;p&gt;Atennissen: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page describes the states of operation that apply to a BCI2000 system as a whole.&lt;br /&gt;
These are different from concept of [[State definition|BCI2000 States]] which are saved to data files on a per-data block basis.&lt;br /&gt;
&lt;br /&gt;
Driven by user interaction from the operator module, the system cycles through five phases of operation:&lt;br /&gt;
Startup, Initialization, Suspended, Running, Termination.&lt;br /&gt;
&lt;br /&gt;
===State Diagram===&lt;br /&gt;
&lt;br /&gt;
 Startup -&amp;gt; Initialization &amp;lt;-&amp;gt; Suspended -&amp;gt; Termination&lt;br /&gt;
                                   ^&lt;br /&gt;
                                   |&lt;br /&gt;
                                   v&lt;br /&gt;
                                Running&lt;br /&gt;
&lt;br /&gt;
==System Startup==&lt;br /&gt;
===Introduction===&lt;br /&gt;
Since the&lt;br /&gt;
system is a&lt;br /&gt;
distributed system of encapsulated modules, this procedure ensures a&lt;br /&gt;
proper and&lt;br /&gt;
well defined information flow at start-up.&lt;br /&gt;
Each module publishes its requests for parameters and states to&lt;br /&gt;
the Operator module, which configures those and sends them back.&lt;br /&gt;
After Data Acquisition receives all parameters and states, it tries to&lt;br /&gt;
connect&lt;br /&gt;
to Signal Processing and -- upon successful connection -- sends a&lt;br /&gt;
positive status&lt;br /&gt;
message to the Operator.&lt;br /&gt;
In the same way, Signal Processing connects to the Application and the&lt;br /&gt;
Application module connects to the Data Acquisition module.&lt;br /&gt;
After the Operator receives status messages from all three core&lt;br /&gt;
modules, the&lt;br /&gt;
system is fully initialized and is triggered to start, as soon as the&lt;br /&gt;
Operator&lt;br /&gt;
sends the state &amp;lt;tt&amp;gt;Running&amp;lt;/tt&amp;gt; with a value of 1 to the Data&lt;br /&gt;
Acquisition module.&lt;br /&gt;
&lt;br /&gt;
===Startup Sequence===&lt;br /&gt;
The operator module must be started first. Since in most cases the IP&lt;br /&gt;
address of&lt;br /&gt;
the operator module can be more easily statically defined, its IP&lt;br /&gt;
address and&lt;br /&gt;
port number(s) have to be provided to the core modules.&lt;br /&gt;
The operator module listens on ports 4000&lt;br /&gt;
(for Source), 4001 (for Signal Processing), and 4002 (for Application)&lt;br /&gt;
and&lt;br /&gt;
waits for the respective core module to connect. Each can connect to&lt;br /&gt;
its&lt;br /&gt;
assigned port on the operator module in any order. Upon start-up,&lt;br /&gt;
each core&lt;br /&gt;
module opens a listening socket on an arbitrary port number.&lt;br /&gt;
&lt;br /&gt;
===Publishing Phase===&lt;br /&gt;
Upon connection, each core module publishes its parameters to the&lt;br /&gt;
operator module as a sequence of [[BCI2000 messages|parameter messages]].&lt;br /&gt;
After&lt;br /&gt;
publishing its&lt;br /&gt;
parameters, each core module publishes the states it requests as&lt;br /&gt;
a sequence of [[BCI2000 messages|state messages]].&lt;br /&gt;
At this time, the operator module ignores&lt;br /&gt;
every&lt;br /&gt;
field except &#039;&#039;Name&#039;&#039;  and &#039;&#039;Length&#039;&#039; , which it needs to&lt;br /&gt;
construct the&lt;br /&gt;
state vector.&lt;br /&gt;
For this and all subsequent communication, the modules use the [[BCI2000 messages]]&lt;br /&gt;
protocol. Following the last&lt;br /&gt;
state, each core module sends a system command containing the string&lt;br /&gt;
&amp;lt;tt&amp;gt;EndOfState&amp;lt;/tt&amp;gt;.&lt;br /&gt;
On receiving this command from all core modules, the operator module&lt;br /&gt;
processes the received parameters and states. It&lt;br /&gt;
creates a&lt;br /&gt;
list of all parameters and all states and creates the state vector&lt;br /&gt;
(duplicate&lt;br /&gt;
parameters or states are ignored), and ends&lt;br /&gt;
this initial publishing phase.&lt;br /&gt;
In order to maintain integrity throughout operation, no parameters or&lt;br /&gt;
states&lt;br /&gt;
should be added to or removed from the system beyond this point.&lt;br /&gt;
&lt;br /&gt;
==System Initialization==&lt;br /&gt;
===Information Phase===&lt;br /&gt;
At this point, the operator module&lt;br /&gt;
may modify&lt;br /&gt;
the value of the parameters and states (depending on the&lt;br /&gt;
investigator&#039;s input or&lt;br /&gt;
the parameter file). The operator module then uses the same channel on&lt;br /&gt;
which it&lt;br /&gt;
received data from the core modules to send back to all core modules a&lt;br /&gt;
list of&lt;br /&gt;
all system-wide parameters and system-wide states (in any order).&lt;br /&gt;
Since the IP&lt;br /&gt;
address and port number on which the core modules listen for data from&lt;br /&gt;
other&lt;br /&gt;
core modules are published in system parameters as described, each&lt;br /&gt;
module now&lt;br /&gt;
knows where to send its data. The connections from the core modules to&lt;br /&gt;
the&lt;br /&gt;
operator module remain open (all subsequent traffic will go through&lt;br /&gt;
these&lt;br /&gt;
connections).&lt;br /&gt;
As in the publishing phase, the Information Phase ends when a system&lt;br /&gt;
command&lt;br /&gt;
&amp;lt;tt&amp;gt;EndOfState&amp;lt;/tt&amp;gt; is sent.&lt;br /&gt;
&lt;br /&gt;
===Preflight Phase===&lt;br /&gt;
In the preflight phase, each core module declares whether it can process data with the&lt;br /&gt;
received parameters and states, and reports the properties of its output signal.&lt;br /&gt;
&lt;br /&gt;
The operator module opens the preflight phase by sending an empty [[BCI2000 messages|signal message]] to the source module.&lt;br /&gt;
The source module then reports its output signal properties to the signal processing module by sending it an appropriate signal message that acts as a template for further signal messages.&lt;br /&gt;
The signal processing module, in turn, sends a signal template to the application module.&lt;br /&gt;
&lt;br /&gt;
During the preflight phase, modules indicate errors by sending descriptions&lt;br /&gt;
into an error channel.&lt;br /&gt;
If any errors are indicated during the preflight phase, the module will not initiate the initialization phase; the operator module will display the errors, prompting the user to fix the problems detected, and not offer the &amp;quot;Start&amp;quot; option.&lt;br /&gt;
&lt;br /&gt;
===Initialization Phase===&lt;br /&gt;
Each core module uses the information in the received parameters to&lt;br /&gt;
configure and&lt;br /&gt;
initialize its operation. It also opens an active (i.e., client)&lt;br /&gt;
connection&lt;br /&gt;
to the other core module it must connect to, i.e., Source opens a&lt;br /&gt;
connection to Signal Processing, Signal Processing to Application and&lt;br /&gt;
Application to Source.&lt;br /&gt;
Each core module sends a [[BCI2000 messages|status message]]&lt;br /&gt;
to the&lt;br /&gt;
operator that indicates either successful or failed initialization.&lt;br /&gt;
The&lt;br /&gt;
Initialization Phase ends when all core modules indicate successful&lt;br /&gt;
configuration.&lt;br /&gt;
&lt;br /&gt;
==System is Suspended==&lt;br /&gt;
At the end of the Initialization Phase, the system is fully&lt;br /&gt;
configured. All&lt;br /&gt;
parameters and states (and positions thereof in the state vector) are&lt;br /&gt;
defined.&lt;br /&gt;
The system is suspended when &#039;&#039;Running&#039;&#039;  is 0. Any module shall&lt;br /&gt;
disregard a&lt;br /&gt;
change in parameters if the system is not suspended. Data flows&lt;br /&gt;
through the&lt;br /&gt;
system and it is up to each module to decide how to process these&lt;br /&gt;
data. The&lt;br /&gt;
Application, for example, might give visual feedback that indicates&lt;br /&gt;
that the&lt;br /&gt;
system is suspended. As long as operation is suspended (i.e.,&lt;br /&gt;
&#039;&#039;Running&#039;&#039; &lt;br /&gt;
is 0), any module might update system parameters and send them back to&lt;br /&gt;
the&lt;br /&gt;
Operator.&lt;br /&gt;
&lt;br /&gt;
==System is Running==&lt;br /&gt;
During system operation, the Operator module must send states only to&lt;br /&gt;
the Source&lt;br /&gt;
module; Signal Processing and Application must disregard any state&lt;br /&gt;
that the&lt;br /&gt;
Operator does send to them.&lt;br /&gt;
The system is started when the Operator module sets the state&lt;br /&gt;
&#039;&#039;Running&#039;&#039; &lt;br /&gt;
to 1 and sends it to the Source module.&lt;br /&gt;
&lt;br /&gt;
==System Termination==&lt;br /&gt;
To each of the three core modules, the operator module indicates&lt;br /&gt;
system termination&lt;br /&gt;
by closing the connection to that module.&lt;br /&gt;
&lt;br /&gt;
When a core module loses connection to the two other core modules it&lt;br /&gt;
is connected&lt;br /&gt;
to, it will send an error message to the operator, and then quit.&lt;br /&gt;
The operator module, in turn, will close the connections to the&lt;br /&gt;
remaining core&lt;br /&gt;
modules.&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
See also:&lt;/div&gt;</summary>
		<author><name>Atennissen</name></author>
	</entry>
	<entry>
		<id>https://www.bci2000.org/mediawiki/index.php?title=Programming_Reference:GenericFilter_Class&amp;diff=1753</id>
		<title>Programming Reference:GenericFilter Class</title>
		<link rel="alternate" type="text/html" href="https://www.bci2000.org/mediawiki/index.php?title=Programming_Reference:GenericFilter_Class&amp;diff=1753"/>
		<updated>2007-05-07T20:08:04Z</updated>

		<summary type="html">&lt;p&gt;Atennissen: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==The &amp;lt;tt&amp;gt;GenericFilter&amp;lt;/tt&amp;gt; class==&lt;br /&gt;
&amp;lt;tt&amp;gt;GenericFilter&amp;lt;/tt&amp;gt; is a base class that provides a programming&lt;br /&gt;
interface for all user code inside the core modules of this BCI2000&lt;br /&gt;
implementation.&lt;br /&gt;
Programming your own data acquisition module, your own filter inside&lt;br /&gt;
Signal Processing, or your own application, implies deriving your&lt;br /&gt;
own&lt;br /&gt;
class from &amp;lt;tt&amp;gt;GenericFilter&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&amp;lt;tt&amp;gt;GenericFilter&amp;lt;/tt&amp;gt;&#039;s member functions represent the various&lt;br /&gt;
initialization and processing events that occur during system startup&lt;br /&gt;
and operation (see [[States of Operation]]).&lt;br /&gt;
Your own filter code &#039;&#039;must&#039;&#039;  implement its own&lt;br /&gt;
versions of some of these member functions:&lt;br /&gt;
&lt;br /&gt;
==Required Members==&lt;br /&gt;
===Constructor===&lt;br /&gt;
The &#039;&#039;Constructor&#039;&#039;, besides its general purpose of initializing member data, declares the parameters and states your filter wants to introduce into the system (the &amp;lt;tt&amp;gt;BEGIN_...&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;END_...&amp;lt;/tt&amp;gt; macros handle the actual function calls): &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 MyFilter::MyFilter()&lt;br /&gt;
 : mMyParam( 1 ),&lt;br /&gt;
   mMyOtherParam( 0.1 ),&lt;br /&gt;
   mCount( 0 )&lt;br /&gt;
 {&lt;br /&gt;
   BEGIN_PARAMETER_DEFINITIONS&lt;br /&gt;
     &amp;quot;MySection int MyParam= 1 &amp;quot;&lt;br /&gt;
       &amp;quot;0 0 3 // This is range-checked between 0 and 3&amp;quot;,&lt;br /&gt;
     &amp;quot;MySection float MyOtherParam= 0.1 &amp;quot;&lt;br /&gt;
       &amp;quot;0 0 0 // This is not automatically range-checked&amp;quot;,&lt;br /&gt;
   END_PARAMETER_DEFINITIONS&lt;br /&gt;
&lt;br /&gt;
   BEGIN_STATE_DEFINITIONS&lt;br /&gt;
     &amp;quot;MyState 1 0 0 0&amp;quot;,&lt;br /&gt;
   END_STATE_DEFINITIONS&lt;br /&gt;
 } &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Preflight===&lt;br /&gt;
The &amp;lt;tt&amp;gt;Preflight&amp;lt;/tt&amp;gt; function checks whether the preconditions for successful operation are met. This function is called whenever parameter values are re- applied, i.e., whenever the user presses &amp;quot;Set Config&amp;quot;, &amp;quot;Start&amp;quot;, or &amp;quot;Resume&amp;quot; in the operator window. If &amp;lt;tt&amp;gt;Preflight&amp;lt;/tt&amp;gt; does not report an error via &amp;lt;tt&amp;gt;bcierr&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;Initialize&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;Process&amp;lt;/tt&amp;gt; will work properly with the current parameters. The first argument to &amp;lt;tt&amp;gt;Preflight&amp;lt;/tt&amp;gt; will inform you about what kind of input signal your filter is going to receive, and your filter is expected to report the properties of its output signal via the second parameter:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 void MyFilter::Preflight( const SignalProperties&amp;amp; inputProperties,&lt;br /&gt;
                                 SignalProperties&amp;amp; outputProperties ) const&lt;br /&gt;
 {&lt;br /&gt;
   PreflightCondition( Parameter( &amp;quot;MyOtherParam&amp;quot; ) &amp;gt; 0.0 );&lt;br /&gt;
   PreflightCondition( inputProperties.Channels() &amp;gt; 0 );&lt;br /&gt;
   PreflightCondition( inputProperties.MaxElements( 0 ) &amp;gt; 0 );&lt;br /&gt;
   outputProperties = inputProperties;&lt;br /&gt;
 } &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note that the &amp;lt;tt&amp;gt;const&amp;lt;/tt&amp;gt; keyword following the function argument list forbids altering any data member of your filter object. This avoids diffusion of initialization code from &amp;lt;tt&amp;gt;Initialize&amp;lt;/tt&amp;gt; into &amp;lt;tt&amp;gt;Preflight&amp;lt;/tt&amp;gt;. If you have your own sub-objects instantiated and maintained by your filter, you should provide them with their own &amp;lt;tt&amp;gt;Preflight() const&amp;lt;/tt&amp;gt; member functions, and call these from your filter&#039;s &amp;lt;tt&amp;gt;Preflight&amp;lt;/tt&amp;gt;. &lt;br /&gt;
*&amp;lt;tt&amp;gt;Initialize&amp;lt;/tt&amp;gt; is called after a successful &amp;lt;tt&amp;gt;Preflight&amp;lt;/tt&amp;gt;. Thus, it may safely omit all checks related to parameter consistency. In &amp;lt;tt&amp;gt;Initialize&amp;lt;/tt&amp;gt;, your filter&#039;s data members are set to the values implied by the user&#039;s choices, or to the initial values required for the filter&#039;s operation:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 void MyFilter::Initialize()&lt;br /&gt;
 {&lt;br /&gt;
   mMyParam = Parameter( &amp;quot;MyParam&amp;quot; );&lt;br /&gt;
   mMyOtherParam = Parameter( &amp;quot;MyOtherParam&amp;quot; );&lt;br /&gt;
   mCount = 0;&lt;br /&gt;
 } &amp;lt;/pre&amp;gt; &lt;br /&gt;
&lt;br /&gt;
===Process===&lt;br /&gt;
The &amp;lt;tt&amp;gt;Process&amp;lt;/tt&amp;gt; function is called once for each block of EEG data. It receives an input in its first argument, and sets the output signal to values resulting from the filter operation. In the current BCI2000 implementation, there is a single chain of filters; one filter&#039;s output signal is the next filter&#039;s input. A filter which does not perform any modification to the signal (e.g., a statistics filter) needs to copy its input signal into the output signal, as in the example:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 void MyFilter::Process( const GenericSignal* inputSignal,&lt;br /&gt;
                               GenericSignal* outputSignal )&lt;br /&gt;
 {&lt;br /&gt;
   if( ( *inputSignal )( 0, 0 ) &amp;gt; mMyOtherParam )&lt;br /&gt;
     ++mCount;&lt;br /&gt;
   *outputSignal = *inputSignal;&lt;br /&gt;
 } &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;tt&amp;gt;Process&amp;lt;/tt&amp;gt; function should not acquire or release resources (opening/closing files, allocating memory, etc). Natural places for such operations are the &amp;lt;tt&amp;gt;Initialize&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;StartRun&amp;lt;/tt&amp;gt;, and &amp;lt;tt&amp;gt;StopRun&amp;lt;/tt&amp;gt; member functions.&lt;br /&gt;
&lt;br /&gt;
==Optional Member Functions==&lt;br /&gt;
Other member functions are &#039;&#039;optional;&#039;&#039;  you may decide whether&lt;br /&gt;
you&lt;br /&gt;
override their default implementation with your own version,&lt;br /&gt;
depending on what your filter needs to do:&lt;br /&gt;
  &lt;br /&gt;
===StartRun===&lt;br /&gt;
&amp;lt;tt&amp;gt;StartRun&amp;lt;/tt&amp;gt; is called when the system enters the running state. As opposed to &amp;lt;tt&amp;gt;Initialize&amp;lt;/tt&amp;gt;, which is the place for tasks that need to be performed on each parameter change, &amp;lt;tt&amp;gt;StartRun&amp;lt;/tt&amp;gt; is provided for tasks that need to be performed each time the user clicks &amp;quot;Run&amp;quot; or &amp;quot;Resume&amp;quot; in the operator window. As a canonical example, the &amp;lt;tt&amp;gt;DataIOFilter&amp;lt;/tt&amp;gt; opens a new &amp;lt;tt&amp;gt;.dat&amp;lt;/tt&amp;gt; file from its &amp;lt;tt&amp;gt;StartRun&amp;lt;/tt&amp;gt; member function. By default, &amp;lt;tt&amp;gt;StartRun&amp;lt;/tt&amp;gt; calls &amp;lt;tt&amp;gt;Initialize&amp;lt;/tt&amp;gt; to make sure that intermittent parameter changes are applied. If you provide your own &amp;lt;tt&amp;gt;StartRun&amp;lt;/tt&amp;gt; function, you will probably want to call &amp;lt;tt&amp;gt;Initialize&amp;lt;/tt&amp;gt; from there as well. &lt;br /&gt;
*&amp;lt;tt&amp;gt;StopRun&amp;lt;/tt&amp;gt; is called each time the system leaves the running state, entering the suspended state. Typically, this happens whenever the user clicks &amp;quot;Suspend&amp;quot; in the operator window. The &amp;lt;tt&amp;gt;DataIOFilter&amp;lt;/tt&amp;gt; provides an example for its usage: This filter closes the current &amp;lt;tt&amp;gt;.dat&amp;lt;/tt&amp;gt; file from its &amp;lt;tt&amp;gt;StopRun&amp;lt;/tt&amp;gt; member function. &amp;lt;tt&amp;gt;StopRun&amp;lt;/tt&amp;gt; is also the only function from which a filter may change a parameter value. Any parameter changes inside &amp;lt;tt&amp;gt;StopRun&amp;lt;/tt&amp;gt; will propagate to the other modules without any explicit request from your side. &lt;br /&gt;
&lt;br /&gt;
===Resting===&lt;br /&gt;
&amp;lt;tt&amp;gt;Resting&amp;lt;/tt&amp;gt; is called instead of &amp;lt;tt&amp;gt;Process&amp;lt;/tt&amp;gt; while the system is in suspended state. &lt;br /&gt;
&lt;br /&gt;
===Halt===&lt;br /&gt;
The &amp;lt;tt&amp;gt;Halt&amp;lt;/tt&amp;gt; function is called before any reconfiguration of the system takes place. If your filter initiates asynchronous operations such as playing a sound file, acquiring EEG data, or executing threads, its &amp;lt;tt&amp;gt;Halt&amp;lt;/tt&amp;gt; member function should terminate all such operations immediately. Failure to do so might result in a non-responding module, or in other errors difficult to track down. For descendants of &amp;lt;tt&amp;gt;GenericADC&amp;lt;/tt&amp;gt;, implementing the &amp;lt;tt&amp;gt;Halt&amp;lt;/tt&amp;gt; function is mandatory. &lt;br /&gt;
&lt;br /&gt;
===Destructor===&lt;br /&gt;
Your filter&#039;s &#039;&#039;Destructor&#039;&#039;  should free all resources acquired in the Constructor or in &amp;lt;tt&amp;gt;Initialize&amp;lt;/tt&amp;gt;. In many cases, freeing of resources will be done automatically if you use direct members instead of pointers, removing the need for a destructor. However, if your filter has a non-empty &amp;lt;tt&amp;gt;Halt&amp;lt;/tt&amp;gt; function, it needs a destructor that calls &amp;lt;tt&amp;gt;Halt&amp;lt;/tt&amp;gt; - this can not be done from the base class destructor because overridden virtual functions cannot be called from base class constructors or destructors.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 MyFilter::~MyFilter()&lt;br /&gt;
 {&lt;br /&gt;
   Halt();&lt;br /&gt;
 } &amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>Atennissen</name></author>
	</entry>
	<entry>
		<id>https://www.bci2000.org/mediawiki/index.php?title=Programming_Reference:Errors_and_Warnings&amp;diff=1752</id>
		<title>Programming Reference:Errors and Warnings</title>
		<link rel="alternate" type="text/html" href="https://www.bci2000.org/mediawiki/index.php?title=Programming_Reference:Errors_and_Warnings&amp;diff=1752"/>
		<updated>2007-05-07T19:47:55Z</updated>

		<summary type="html">&lt;p&gt;Atennissen: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Output Streams==&lt;br /&gt;
There are two output channels available to any code inside a BCI2000&lt;br /&gt;
module.&lt;br /&gt;
Technically, these channels are global objects derived from the STL&#039;s&lt;br /&gt;
&amp;lt;tt&amp;gt;std::ostream&amp;lt;/tt&amp;gt; class. As such, they work much like the global&lt;br /&gt;
&amp;lt;tt&amp;gt;std::cout&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;std::cerr&amp;lt;/tt&amp;gt; output streams available&lt;br /&gt;
inside a&lt;br /&gt;
C++ command line program, except that their output will be sent to the&lt;br /&gt;
operator&lt;br /&gt;
module&#039;s log window rather than a terminal window.&lt;br /&gt;
&lt;br /&gt;
==Writing into Error and Warning Streams==&lt;br /&gt;
The names of these output streams are &amp;lt;tt&amp;gt;bciout&amp;lt;/tt&amp;gt; and&lt;br /&gt;
&amp;lt;tt&amp;gt;bcierr&amp;lt;/tt&amp;gt;,&lt;br /&gt;
declared in &amp;lt;tt&amp;gt;shared/BCIError.h&amp;lt;/tt&amp;gt;, and while writing output to&lt;br /&gt;
&amp;lt;tt&amp;gt;bciout&amp;lt;/tt&amp;gt; has no side effects, writing to &amp;lt;tt&amp;gt;bcierr&amp;lt;/tt&amp;gt; has&lt;br /&gt;
side effects that depend on the system&#039;s phase of operation:&lt;br /&gt;
In preflight phase, the side effect will be a preflight failure, and the system will not start&lt;br /&gt;
unless reconfigured with correct parameters; otherwise, the side effect will&lt;br /&gt;
be system termination after error display.&lt;br /&gt;
&lt;br /&gt;
Note that writing into &amp;lt;tt&amp;gt;bcierr&amp;lt;/tt&amp;gt; or &amp;lt;tt&amp;gt;bciout&amp;lt;/tt&amp;gt; has no effect before the stream&#039;s output buffer is flushed by inserting &amp;lt;tt&amp;gt;endl&amp;lt;/tt&amp;gt; or &amp;lt;tt&amp;gt;flush&amp;lt;/tt&amp;gt;:&lt;br /&gt;
 bcierr &amp;lt;&amp;lt; &amp;quot;Display this immediately!&amp;quot; &amp;lt;&amp;lt; endl;&lt;br /&gt;
&lt;br /&gt;
==Convenience Macros==&lt;br /&gt;
For the &amp;lt;tt&amp;gt;Preflight&amp;lt;/tt&amp;gt; function, there is also a macro&lt;br /&gt;
&amp;lt;tt&amp;gt;PreflightCondition&amp;lt;/tt&amp;gt; available that is intended to make&lt;br /&gt;
checking&lt;br /&gt;
for conditions more convenient:&lt;br /&gt;
 PreflightCondition( Parameter( &amp;quot;MyFirstParam&amp;quot; ) &amp;gt;= 3 );&lt;br /&gt;
will result in a message&lt;br /&gt;
 &amp;quot;A necessary condition is violated: Parameter( &amp;quot;MyFirstParam&amp;quot; ) &amp;gt;= 3&amp;quot;&lt;br /&gt;
in the operator window if &amp;lt;tt&amp;gt;MyFirstParam&amp;lt;/tt&amp;gt;&#039;s value is below 3.&lt;br /&gt;
&lt;br /&gt;
==Throwing Exceptions==&lt;br /&gt;
Finally, in case of a non-recoverable error, you may also throw an&lt;br /&gt;
exception&lt;br /&gt;
of type &amp;lt;tt&amp;gt;const char*&amp;lt;/tt&amp;gt; in order to report an error in the&lt;br /&gt;
operator window,&lt;br /&gt;
and to terminate the BCI2000 system after the error has been&lt;br /&gt;
displayed:&lt;br /&gt;
 throw __FUNC__ &amp;quot;: Disk space is exhausted&amp;quot;;&lt;br /&gt;
-----&lt;br /&gt;
See also: [[Error Handling]] for a more detailed discussion of error reporting facilities.&lt;/div&gt;</summary>
		<author><name>Atennissen</name></author>
	</entry>
	<entry>
		<id>https://www.bci2000.org/mediawiki/index.php?title=Technical_Reference:Parameter_Definition&amp;diff=1751</id>
		<title>Technical Reference:Parameter Definition</title>
		<link rel="alternate" type="text/html" href="https://www.bci2000.org/mediawiki/index.php?title=Technical_Reference:Parameter_Definition&amp;diff=1751"/>
		<updated>2007-05-07T19:43:53Z</updated>

		<summary type="html">&lt;p&gt;Atennissen: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page describes the concept of BCI2000 parameters, in conjunction with their textual representation as a &amp;quot;parameter line&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
For information about how to access parameters from code, please refer to [[Programming Reference:Parameters]].&lt;br /&gt;
For information about individual parameters, please refer to [[User Reference:Parameters]].&lt;br /&gt;
&lt;br /&gt;
==Parameter Concept==&lt;br /&gt;
Parameters are variables that primarily represent user configuration choices. Typical entities encoded by parameters are:&lt;br /&gt;
*size and location of the feedback window &lt;br /&gt;
*subject ID&lt;br /&gt;
*sampling rate&lt;br /&gt;
*spatial filtering matrix.&lt;br /&gt;
&lt;br /&gt;
Typically, parameters are constant throughout a run, often throughout a session or an entire experiment.&lt;br /&gt;
In a [[BCI2000 data file]], a full set of parameters is stored along with the data, allowing for reconstruction of the system configuration off-line.&lt;br /&gt;
&lt;br /&gt;
As parameters represent user choices, the direction of information flow generally is Parameter Value-&amp;gt;BCI2000 Module, i.e. parameter information is used to set BCI2000 modules to a defined state at initialization time.&lt;br /&gt;
There are, however, some important exceptions to that rule.&lt;br /&gt;
*&#039;&#039;Source Modules&#039;&#039; may not be able to control all aspects of data acquisition. Control is limited by the design of the vendor-provided software interface to data acquisition hardware. As a typcial example, consider an EEG amplifier connected through a TCP-based socket interface. Generally, the amplifier will be configured in a separate user interface, and BCI2000 source module parameters such as &amp;lt;tt&amp;gt;SourceCh&amp;lt;/tt&amp;gt; (number of channels) or &amp;lt;tt&amp;gt;SamplingRate&amp;lt;/tt&amp;gt; must be chosen in accordance with that external UI&#039;s settings.&lt;br /&gt;
*&#039;&#039;System-internal Configuration&#039;&#039; is represented as parameters, and of potential interest to the user, but not user configurable. These parameters are placed in the configuration editor&#039;s &#039;&#039;System&#039;&#039; tab. Important examples comprise versioning information (e.g., the &amp;lt;tt&amp;gt;EEGSourceVersion&amp;lt;/tt&amp;gt; parameter), others govern the connection between modules (e.g., the &amp;lt;tt&amp;gt;EEGSourceIP&amp;lt;/tt&amp;gt; parameter).&lt;br /&gt;
*&#039;&#039;Automatic Adaptation&#039;&#039; to the subject&#039;s brain signals may be reflected by automatically updated parameters. For such parameters, the user specifies initial parameter values that may be overwritten at the end of a run. Unless changed by the user, these modified values will be the next run&#039;s initial values, and documented as such in that run&#039;s data file. As typical examples, consider the &#039;&#039;Normalizer&#039;&#039; filter&#039;s  &amp;lt;tt&amp;gt;NormalizerOffsets&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;NormalizerGains&amp;lt;/tt&amp;gt; parameters.&lt;br /&gt;
&lt;br /&gt;
==Parameter Lines==&lt;br /&gt;
Parameter lines are a human-readable format used to represent individual parameters in:&lt;br /&gt;
*[[BCI2000 parameter files]]&lt;br /&gt;
*[[BCI2000 data files]]&lt;br /&gt;
*[[BCI2000 messages]] sent between modules.&lt;br /&gt;
&lt;br /&gt;
The basic format of a parameter line is&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Section DataType Name= Value DefaultValue LowRange HighRange // Comment&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Note that the = sign must follow the &amp;lt;tt&amp;gt;Name&amp;lt;/tt&amp;gt; field immediately, without&lt;br /&gt;
white space. However, white space &#039;&#039;after&#039;&#039; the = sign is mandatory.&lt;br /&gt;
&lt;br /&gt;
If DataType is &#039;&#039;list, intlist&#039;&#039;  or &#039;&#039;floatlist&#039;&#039;, the format is as follows:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Section DataType Name= (NumValues|Labels) Value(s) DefaultValue LowRange HighRange &lt;br /&gt;
  // Comment&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
where &amp;lt;tt&amp;gt;Labels&amp;lt;/tt&amp;gt; is a list of textual labels that optionally&lt;br /&gt;
substitute the number denoted by &amp;lt;tt&amp;gt;NumValues&amp;lt;/tt&amp;gt;. A list of labels&lt;br /&gt;
is enclosed by &amp;lt;nowiki&amp;gt;{} or []&amp;lt;/nowiki&amp;gt;, as in&lt;br /&gt;
&amp;lt;tt&amp;gt;&amp;lt;nowiki&amp;gt;[low medium high]&amp;lt;/nowiki&amp;gt;&amp;lt;/tt&amp;gt;.&lt;br /&gt;
If DataType is &#039;&#039;matrix&#039;&#039; , the format is as follows:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Section DataType Name= (NumRows|RowLabels)&lt;br /&gt;
    (NumColumns|ColumnLabels) Value(s) DefaultValue LowRange&lt;br /&gt;
    HighRange // Comment&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
where, again, each NumValues entry may be substituted by a list of&lt;br /&gt;
textual labels.&lt;br /&gt;
For matrices, values are given in column-major order, i.e. listing&lt;br /&gt;
values from the first column first, then values from the second column,&lt;br /&gt;
and so on, as in&lt;br /&gt;
 Value(0,0) Value(0,1) ... Value(0,m) Value(1,0) Value(1,1) ... Value(1,m) ...&lt;br /&gt;
&lt;br /&gt;
===Data Types===&lt;br /&gt;
The DataType field is not interpreted in a very strict sense. &lt;br /&gt;
Rather, parameter values are always stored as strings, and converted into&lt;br /&gt;
numerical values only when accessed as such from BCI2000 modules.&lt;br /&gt;
For consistency, and to avoid user confusion, the following primitive types&lt;br /&gt;
should be specified as appropriate:&lt;br /&gt;
{|border=&amp;quot;1&amp;quot;&lt;br /&gt;
|+ Primitive Parameter Data Types&lt;br /&gt;
! Name !! Description&lt;br /&gt;
|-&lt;br /&gt;
| variant || unspecified type&lt;br /&gt;
|-&lt;br /&gt;
| int || unlimited range integer value&lt;br /&gt;
|-&lt;br /&gt;
| float || unlimited range, arbitrary precision float value&lt;br /&gt;
|-&lt;br /&gt;
| string || any string of characters (see the &#039;&#039;Special characters&#039;&#039; section for details)&lt;br /&gt;
|}&lt;br /&gt;
A list or matrix type may be formed from these primitive types when concatenated with &#039;&#039;list&#039;&#039; or &#039;&#039;matrix&#039;&#039;, as in &#039;&#039;intlist&#039;&#039;, &#039;&#039;stringmatrix&#039;&#039;.&lt;br /&gt;
For a list or matrix with entries of unspecified type, use an unprefixed &#039;&#039;list&#039;&#039; or &#039;&#039;matrix&#039;&#039; rather than &#039;&#039;variantlist&#039;&#039; or &#039;&#039;variantmatrix&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
===Special characters===&lt;br /&gt;
To allow for special characters and&lt;br /&gt;
white space&lt;br /&gt;
within parameter values and textual labels, an URL-like encoding&lt;br /&gt;
scheme is adopted.&lt;br /&gt;
In this encoding, a &amp;lt;tt&amp;gt;%&amp;lt;/tt&amp;gt; character followed by up to two &lt;br /&gt;
hexadecimal digits&lt;br /&gt;
represents a byte value in hexadecimal notation which is interpreted&lt;br /&gt;
according to&lt;br /&gt;
the ASCII-Latin1 character table.&lt;br /&gt;
Thus, &amp;lt;tt&amp;gt;%20&amp;lt;/tt&amp;gt; represents a space character, and&lt;br /&gt;
&amp;lt;tt&amp;gt;%&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;%0&amp;lt;/tt&amp;gt;, and &amp;lt;tt&amp;gt;%00&amp;lt;/tt&amp;gt; all represent an empty string value;&lt;br /&gt;
&amp;lt;tt&amp;gt;%%&amp;lt;/tt&amp;gt; represents the &amp;lt;tt&amp;gt;%&amp;lt;/tt&amp;gt; character itself.&lt;br /&gt;
The line&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Demo string SomeString= a%20string%20with%20spaces % % %&lt;br /&gt;
    // White space example&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
defines a parameter &#039;&#039;SomeString&#039;&#039;  which contains the value&lt;br /&gt;
&#039;&#039;a string&lt;br /&gt;
with spaces&#039;&#039;. &lt;br /&gt;
The single &amp;lt;tt&amp;gt;%&amp;lt;/tt&amp;gt; characters indicate that the &lt;br /&gt;
&#039;&#039;DefaultValue&#039;&#039; ,&lt;br /&gt;
&#039;&#039;LowRange&#039;&#039;  and &#039;&#039;HighRange&#039;&#039;  fields should be empty&lt;br /&gt;
strings.&lt;br /&gt;
&lt;br /&gt;
==Sub-parameters==&lt;br /&gt;
Any parameter value may itself be a sub-parameter.&lt;br /&gt;
Sub-parameters are represented by a short-form&lt;br /&gt;
matrix definition omitting the &#039;&#039;Section&#039;&#039;  and &#039;&#039;Name&#039;&#039; &lt;br /&gt;
fields, enclosed in&lt;br /&gt;
a pair of braces:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Demo matrix NestedMatrices= 1 2 11 { matrix 2 2 1211 1212 1221 1222 }&lt;br /&gt;
    // Nested matrix example&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
will define a matrix parameter whose 1,2 entry is a 2x2 matrix.&lt;br /&gt;
While the syntax allows for any combination of parameter and&lt;br /&gt;
subparameter types,&lt;br /&gt;
the current implementation of the parameter editor GUI only&lt;br /&gt;
supports matrix-type&lt;br /&gt;
sub-parameters within matrices as in the example above.&lt;br /&gt;
&lt;br /&gt;
==Display Format==&lt;br /&gt;
Generally, a parameter&#039;s &amp;lt;tt&amp;gt;DataType&amp;lt;/tt&amp;gt; field will be used to &lt;br /&gt;
determine its appropriate display in a parameter editor.&lt;br /&gt;
However, often a more user-friendly display may be achieved if &lt;br /&gt;
additional information about a parameter&#039;s content is available.&lt;br /&gt;
&lt;br /&gt;
To allow for such information, the comment line that is introduced by the&lt;br /&gt;
two&lt;br /&gt;
slashes (//) may contain a format identifier that is used by the&lt;br /&gt;
Operator module&lt;br /&gt;
to modify the display of the particular parameter. Format identifiers&lt;br /&gt;
are&lt;br /&gt;
strictly optional and are introduced as follows:&lt;br /&gt;
&amp;lt;tt&amp;gt;(identifier)&amp;lt;/tt&amp;gt;.&lt;br /&gt;
Currently, the following format identifiers are implemented:&lt;br /&gt;
&lt;br /&gt;
{| border=&amp;quot;1&amp;quot;&lt;br /&gt;
|+ The currently defined format identifiers&lt;br /&gt;
! Identifier !! Description&lt;br /&gt;
|- &lt;br /&gt;
| &amp;lt;tt&amp;gt;(enumeration)&amp;lt;/tt&amp;gt; || a choice from an enumerated set of values&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;(boolean)&amp;lt;/tt&amp;gt; || a yes/no choice &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;(inputfile)&amp;lt;/tt&amp;gt; || path to a file to be opened for reading &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;(outputfile)&amp;lt;/tt&amp;gt; || path to a file to be opened for writing &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;(directory)&amp;lt;/tt&amp;gt; || path to a directory &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;(color)&amp;lt;/tt&amp;gt; || RGB color &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===&amp;lt;tt&amp;gt;(enumeration)&amp;lt;/tt&amp;gt;===&lt;br /&gt;
The parameter value is presented as a drop down menu, with entries&lt;br /&gt;
corresponding to the&lt;br /&gt;
possible values listed in the comment. The first part of the comment&lt;br /&gt;
appears above&lt;br /&gt;
the drop down menu. All interpunction characters present in the&lt;br /&gt;
comment are ignored.&lt;br /&gt;
The data type of the parameter must be &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;.&lt;br /&gt;
All possible values must appear in the comment, and the parameter&#039;s&lt;br /&gt;
LowRange and HighRange &lt;br /&gt;
fields must be consistent with the enumeration. LowRange will usually&lt;br /&gt;
be 0, but may be any&lt;br /&gt;
integer. For example: &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Breakfast int BreakfastDrink= 1 1 1 3&lt;br /&gt;
  // Drink for breakfast: 1 Tea, 2 Coffee, 3 Juice (enumeration)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
will display a drop down menu with entries &amp;quot;Tea,&amp;quot; &amp;quot;Coffee,&amp;quot;, and&lt;br /&gt;
&amp;quot;Juice.&amp;quot;&lt;br /&gt;
The menu will be labeled &amp;quot;Drink for breakfast.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
===&amp;lt;tt&amp;gt;(boolean)&amp;lt;/tt&amp;gt;===&lt;br /&gt;
The parameter value is presented as a check box; the first part of the&lt;br /&gt;
comment appears&lt;br /&gt;
to the right of the check box. LowRange and HighRange must be 0 and 1.&lt;br /&gt;
The parameter&#039;s data type must be &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;.&lt;br /&gt;
To ensure human readability of parameter files, the possible values&lt;br /&gt;
and their meaning may&lt;br /&gt;
appear in the comment (e. g. &amp;lt;tt&amp;gt;0: no, 1: yes&amp;lt;/tt&amp;gt;) but will not&lt;br /&gt;
be displayed with the&lt;br /&gt;
check box. For example:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Breakfast int ServeBreakfast= 1 1 0 1&lt;br /&gt;
  // Serve breakfast: 0 no, 1 yes (boolean)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
will display a check box labeled &amp;quot;Serve breakfast.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
===&amp;lt;tt&amp;gt;(inputfile)(outputfile)(directory)&amp;lt;/tt&amp;gt;===&lt;br /&gt;
The parameter value is presented as an edit field. Beside the edit&lt;br /&gt;
field, there is a button that opens up a file or directory and selects dialog when clicked.&lt;br /&gt;
The parameter&#039;s data type must be &amp;lt;tt&amp;gt;string&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Breakfast string WakeupSound= doorbell.wav &lt;br /&gt;
  // Sound to play in the morning (inputfile)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===&amp;lt;tt&amp;gt;(color)&amp;lt;/tt&amp;gt;===&lt;br /&gt;
The parameter value is presented as an edit field. To the right of the edit&lt;br /&gt;
field there is a button that opens up a color selector dialog when clicked.&lt;br /&gt;
The parameter&#039;s data type must be &amp;lt;tt&amp;gt;string&amp;lt;/tt&amp;gt;, with its value&lt;br /&gt;
containing the color&lt;br /&gt;
in hexadecimal RGB encoding:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Breakfast string TableClothColor= 0x00FF00 0xFFFFFF 0x000000 0xFFFFFF&lt;br /&gt;
  // Color of table cloth to put up for breakfast (color)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Grouping Parameters by Sections==&lt;br /&gt;
A user interface may use fields in the parameter &amp;lt;tt&amp;gt;Section&amp;lt;/tt&amp;gt; fields to&lt;br /&gt;
collect parameters into&lt;br /&gt;
groups, e.g., by displaying all parameters with identical section&lt;br /&gt;
fields on the same&lt;br /&gt;
register tab of a GUI parameter editor dialog window.&lt;br /&gt;
In the &amp;lt;tt&amp;gt;Section&amp;lt;/tt&amp;gt; field, finer grained grouping may be expressed&lt;br /&gt;
by specifying&lt;br /&gt;
sub-sections separated by colon characters, e.g., a &amp;lt;tt&amp;gt;Section&amp;lt;/tt&amp;gt;&lt;br /&gt;
value of&lt;br /&gt;
&amp;lt;font color=&amp;quot;#cd4b19&amp;quot;&amp;gt;UsrTask:WindowDimensions&amp;lt;/font&amp;gt;&lt;br /&gt;
will indicate that a parameter belongs to a &amp;lt;tt&amp;gt;WindowDimensions&amp;lt;/tt&amp;gt;&lt;br /&gt;
subsection of&lt;br /&gt;
a section called &amp;lt;tt&amp;gt;UsrTask&amp;lt;/tt&amp;gt;. A parameter editor implementation&lt;br /&gt;
might display the respective parameter on a register tab called&lt;br /&gt;
&amp;quot;UsrTask&amp;quot; and&lt;br /&gt;
inside a group box labelled &amp;quot;WindowDimensions&amp;quot;.&lt;br /&gt;
Although any number of sub-sections may be present in the&lt;br /&gt;
&amp;lt;tt&amp;gt;Section&amp;lt;/tt&amp;gt; field,&lt;br /&gt;
a user interface implementation may ignore sub-section entries below a&lt;br /&gt;
level chosen by the implementer.&lt;br /&gt;
-----&lt;br /&gt;
See also: [[User Reference:Parameters]]&lt;/div&gt;</summary>
		<author><name>Atennissen</name></author>
	</entry>
	<entry>
		<id>https://www.bci2000.org/mediawiki/index.php?title=User_Reference:Expression_Syntax&amp;diff=1749</id>
		<title>User Reference:Expression Syntax</title>
		<link rel="alternate" type="text/html" href="https://www.bci2000.org/mediawiki/index.php?title=User_Reference:Expression_Syntax&amp;diff=1749"/>
		<updated>2007-05-07T18:14:10Z</updated>

		<summary type="html">&lt;p&gt;Atennissen: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;BCI2000 contains an &#039;&#039;expression parser&#039;&#039; that evaluates user-defined mathematical expressions at run-time.&lt;br /&gt;
Expression syntax tries to be intuitive and is based on C and Matlab notation.&lt;br /&gt;
&lt;br /&gt;
===Syntactic Elements===&lt;br /&gt;
====&amp;quot;Real&amp;quot; Numbers====&lt;br /&gt;
Numbers may be given as literals in decimal or scientific notation:&lt;br /&gt;
100, 1e2, 100.0, (1000/10)&lt;br /&gt;
all refer to the same number. Complex numbers are not supported.&lt;br /&gt;
&lt;br /&gt;
====Operators====&lt;br /&gt;
;Arithmetic operators: &lt;br /&gt;
:&amp;lt;pre&amp;gt; ^ unary- * / + -&amp;lt;/pre&amp;gt;&lt;br /&gt;
:Unlike C but consistent with Matlab, &amp;lt;code&amp;gt;a^b&amp;lt;/code&amp;gt; evaluates to the b-th power of a.&lt;br /&gt;
&lt;br /&gt;
;Comparison operators: &lt;br /&gt;
:&amp;lt;pre&amp;gt; &amp;lt; &amp;gt; &amp;lt;= &amp;gt;= == != ~=&amp;lt;/pre&amp;gt;&lt;br /&gt;
:Note that a single equals sign is not a valid operator. For the &amp;quot;not equal&amp;quot; operator, the C version (!=) is supported along with the Matlab version (~=).&lt;br /&gt;
&lt;br /&gt;
;Logical operators:&lt;br /&gt;
:&amp;lt;pre&amp;gt; ! ~ &amp;amp;&amp;amp; ||&amp;lt;/pre&amp;gt;&lt;br /&gt;
:Again, ! and ~ are synonymous to match both C and Matlab conventions. When mixing boolean and numerical expression, values need to be converted back and forth between numbers and logical values. As usual, zero is treated as &#039;&#039;false&#039;&#039;, and nonzero values are treated as &#039;&#039;true&#039;&#039;. Reversely, &#039;&#039;false&#039;&#039; is converted into the number 0, and &#039;&#039;true&#039;&#039; is converted into 1. There are no literals for &#039;&#039;true&#039;&#039; and &#039;&#039;false&#039;&#039;; use 0 and 1 instead.&lt;br /&gt;
&lt;br /&gt;
;Condition operator&lt;br /&gt;
:&amp;lt;pre&amp;gt; &amp;lt;condition&amp;gt;?&amp;lt;if-expr&amp;gt;:&amp;lt;else-expr&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
:As in C, the ternary condition operator ?: allows for if-then-else-like constructs. If &#039;&#039;condition&#039;&#039; is true, it evaluates to &#039;&#039;if-expr&#039;&#039;, and to &#039;&#039;else-expr&#039;&#039; otherwise.&lt;br /&gt;
&lt;br /&gt;
;Precedence&lt;br /&gt;
:Operator precedence follows the order of appearance in the above list. As usual, braces ( ) may be used to override operator precedence.&lt;br /&gt;
&lt;br /&gt;
====States====&lt;br /&gt;
Expressions may involve BCI2000 [[States]]. These are referred to by name as in&lt;br /&gt;
&amp;lt;pre&amp;gt;TargetCode==ResultCode&amp;lt;/pre&amp;gt;&lt;br /&gt;
or&lt;br /&gt;
&amp;lt;pre&amp;gt;(TargetCode-1)*ResultCode&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Signal Values====&lt;br /&gt;
Depending on context, expressions may involve signal values:&lt;br /&gt;
&amp;lt;pre&amp;gt;10*Signal(0,3)&amp;lt;/pre&amp;gt;&lt;br /&gt;
Here, &amp;quot;Signal&amp;quot; refers to the filter&#039;s input signal, and indices are &#039;&#039;zero-based&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
===Examples===&lt;br /&gt;
*An expression that evaluates to the ResultCode state only if that equals the TargetCode state (i.e., in case of a successful trial):&lt;br /&gt;
 (ResultCode==TargetCode)?ResultCode:0&lt;br /&gt;
*A mapping of TargetCode values to arbitrary numbers:&lt;br /&gt;
 (TargetCode==0)?3:(TargetCode==1)?-4:(TargetCode==2)?18:0&lt;br /&gt;
&lt;br /&gt;
===Caveats===&lt;br /&gt;
*There is no integer arithmetic. All evaluation is done in floating point, even if only integers are involved. As a result, comparisons may fail unexpectedly, or boolean conversion may always yield true:&lt;br /&gt;
:&amp;lt;pre&amp;gt; x^2-(3/7+4/5)*x+(4/5)*(3/7)==(x-4/5)*(x-3/7)&amp;lt;/pre&amp;gt;&lt;br /&gt;
:should be &#039;&#039;true&#039;&#039; independently of x but will always evaluate to &#039;&#039;false&#039;&#039; due to roundoff errors.&lt;br /&gt;
:In most cases, a numerically robust reformulation of the expression should resolve the problem.&lt;br /&gt;
&lt;br /&gt;
*Sometimes, operator precedence or behavior may not match your intuition. When in doubt, use brackets:&lt;br /&gt;
:&amp;lt;pre&amp;gt;(TargetCode^(-3))/5&amp;lt;/pre&amp;gt;&lt;br /&gt;
:rather than&lt;br /&gt;
:&amp;lt;pre&amp;gt;TargetCode^-3/5&amp;lt;/pre&amp;gt;&lt;br /&gt;
:which is equivalent but may be misunderstood as&lt;br /&gt;
:&amp;lt;pre&amp;gt;TargetCode^(-3/5)&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>Atennissen</name></author>
	</entry>
	<entry>
		<id>https://www.bci2000.org/mediawiki/index.php?title=Technical_Reference:State_Definition&amp;diff=1748</id>
		<title>Technical Reference:State Definition</title>
		<link rel="alternate" type="text/html" href="https://www.bci2000.org/mediawiki/index.php?title=Technical_Reference:State_Definition&amp;diff=1748"/>
		<updated>2007-05-07T18:04:20Z</updated>

		<summary type="html">&lt;p&gt;Atennissen: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page describes the concept of BCI2000 states, in conjunction with their textual representation as a &amp;quot;state line&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
For information about how to access state values from code, please refer to [[Programming Reference:States]].&lt;br /&gt;
For information about individual parameters, please refer to [[User Reference:States]].&lt;br /&gt;
&lt;br /&gt;
==State Concept==&lt;br /&gt;
States are variables that represent the internal state of a BCI2000 system as it is evolving over time in response to:&lt;br /&gt;
*brain signal input&lt;br /&gt;
*user interaction through the operator interface&lt;br /&gt;
*trial sequencing by the application module.&lt;br /&gt;
&lt;br /&gt;
Typical entities encoded by states are:&lt;br /&gt;
*whether the system is running or suspended&lt;br /&gt;
*the time when a block of data was recorded &lt;br /&gt;
*stimulus or task being presented&lt;br /&gt;
*the classification result&lt;br /&gt;
*the state of an external marker (trigger) to be saved for off-line analysis.&lt;br /&gt;
&lt;br /&gt;
Typically, state values change once per block of data, or once per trial.&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
==State Vector==&lt;br /&gt;
In a BCI2000 system, a collection of states is maintained as a &#039;&#039;State List&#039;&#039;.&lt;br /&gt;
For each state present in that state list, its value is kept as a range of bits in a bit vector called &#039;&#039;State Vector&#039;&#039;.&lt;br /&gt;
BCI2000 modules and filters may read and write state values during processing.&lt;br /&gt;
The state vector&#039;s content is saved, in its binary form, into [[BCI2000 data files]] per-block.&lt;br /&gt;
Using the ByteLocation, BitLocation, and Length fields from the state definitions present in a file, a state&#039;s value may be read from the data file.&lt;br /&gt;
&lt;br /&gt;
A state vector is a narrowly packed bit field in &#039;&#039;&#039;big endian&#039;&#039;&#039; ordering.&lt;br /&gt;
This implies that, for a state containing more than a single bit, &#039;&#039;&#039;less&#039;&#039;&#039; significant bits are placed at &#039;&#039;&#039;higher&#039;&#039;&#039; bit and byte locations.&lt;br /&gt;
&lt;br /&gt;
As an example, consider a state vector consisting of a 1-bit state &amp;quot;Running&amp;quot;, and a 16-bit state &amp;quot;SourceTime&amp;quot;. This will result in a three-byte state vector layout like this:&lt;br /&gt;
{|border=&amp;quot;1&amp;quot; cellspacing=&amp;quot;0&amp;quot; cellpadding=&amp;quot;1&amp;quot;&lt;br /&gt;
!colspan=&amp;quot;8&amp;quot;|State Vector Byte 1 &lt;br /&gt;
!colspan=&amp;quot;8&amp;quot;|State Vector Byte 2 &lt;br /&gt;
!colspan=&amp;quot;8&amp;quot;|State Vector Byte 3&lt;br /&gt;
|-&lt;br /&gt;
!7!!6!!5!!4!!3!!2!!1!!0&lt;br /&gt;
!7!!6!!5!!4!!3!!2!!1!!0&lt;br /&gt;
!7!!6!!5!!4!!3!!2!!1!!0&lt;br /&gt;
|-&lt;br /&gt;
!Running!!colspan=&amp;quot;16&amp;quot;|SourceTime!!colspan=&amp;quot;7&amp;quot;|unused&lt;br /&gt;
|-&lt;br /&gt;
!0&lt;br /&gt;
!15!!14!!13!!12!!11!!10!!9!!8!!7!!6!!5!!4!!3!!2!!1!!0&lt;br /&gt;
!colspan=&amp;quot;7&amp;quot;|&amp;amp;nbsp;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==State Lines==&lt;br /&gt;
State lines are a human-readable format used to represent individual states in&lt;br /&gt;
*[[BCI2000 data files]],&lt;br /&gt;
*[[BCI2000 messages]] sent between modules.&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
The format of a state line is&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Name Length Value ByteLocation BitLocation CRLF&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
where &amp;lt;tt&amp;gt;Length&amp;lt;/tt&amp;gt; refers to the number of bits used to represent the state&#039;s value,&lt;br /&gt;
and &amp;lt;tt&amp;gt;ByteLocation&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;BitLocation&amp;lt;/tt&amp;gt; refer to its position in a [[State Vector]], with &amp;lt;tt&amp;gt;BitLocation&amp;lt;/tt&amp;gt; ranging from 0 to 7.&lt;br /&gt;
&lt;br /&gt;
Depending on the context of a state line, one or more of its fields may be ignored:&lt;br /&gt;
*In a State message sent from the operator module to a core module, Length, ByteLocation, and BitLocation will be ignored.&lt;br /&gt;
*In a State line contained in a data file, the Value field matches the state&#039;s value stored with the first block of data samples.&lt;br /&gt;
&lt;br /&gt;
Generally, the Value field specifies an &#039;&#039;initial value&#039;&#039; of a state. Actual values are stored in the [[State Vector]] data structure.&lt;br /&gt;
-----&lt;br /&gt;
See also: [[User Reference:States]]&lt;/div&gt;</summary>
		<author><name>Atennissen</name></author>
	</entry>
	<entry>
		<id>https://www.bci2000.org/mediawiki/index.php?title=Programming_Reference:Signals&amp;diff=1747</id>
		<title>Programming Reference:Signals</title>
		<link rel="alternate" type="text/html" href="https://www.bci2000.org/mediawiki/index.php?title=Programming_Reference:Signals&amp;diff=1747"/>
		<updated>2007-05-07T16:47:43Z</updated>

		<summary type="html">&lt;p&gt;Atennissen: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Signals==&lt;br /&gt;
Many classes in both Data Acquisition and Signal Processing work on&lt;br /&gt;
signals, i.e., continuously flowing data organized in channels and samples.&lt;br /&gt;
The &amp;lt;tt&amp;gt;GenericSignal&amp;lt;/tt&amp;gt; class contains floating point data&lt;br /&gt;
organized as a matrix of channels and &amp;quot;elements&amp;quot; (a generalized&lt;br /&gt;
notion&lt;br /&gt;
of samples -- e.g., spectrally analyzed data might contain the&lt;br /&gt;
spectrum of&lt;br /&gt;
each channel as a list of &amp;quot;elements&amp;quot;).&lt;br /&gt;
&lt;br /&gt;
==Signal Properties==&lt;br /&gt;
Sometimes, the number of channels, elements, and bytes&lt;br /&gt;
required&lt;br /&gt;
for storing values, are referred to as &amp;quot;Signal Properties&amp;quot;.&lt;br /&gt;
There is a separate class, &amp;lt;tt&amp;gt;SignalProperties&amp;lt;/tt&amp;gt;, for expressing&lt;br /&gt;
those&lt;br /&gt;
values, and determining whether a given signal &amp;quot;fits&amp;quot; into another&lt;br /&gt;
one, i.e., &lt;br /&gt;
whether the values contained in one signal may be copied into another&lt;br /&gt;
signal without loss of information.&lt;br /&gt;
&amp;lt;tt&amp;gt;GenericSignal&amp;lt;/tt&amp;gt; uses a &amp;lt;tt&amp;gt;SignalProperties&amp;lt;/tt&amp;gt; member to&lt;br /&gt;
maintain&lt;br /&gt;
information about its properties.&lt;/div&gt;</summary>
		<author><name>Atennissen</name></author>
	</entry>
	<entry>
		<id>https://www.bci2000.org/mediawiki/index.php?title=Programming_Reference:Environment_Class&amp;diff=1746</id>
		<title>Programming Reference:Environment Class</title>
		<link rel="alternate" type="text/html" href="https://www.bci2000.org/mediawiki/index.php?title=Programming_Reference:Environment_Class&amp;diff=1746"/>
		<updated>2007-05-07T16:42:33Z</updated>

		<summary type="html">&lt;p&gt;Atennissen: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Your code&#039;s &amp;lt;tt&amp;gt;Environment&amp;lt;/tt&amp;gt;==&lt;br /&gt;
In each BCI2000 module, there exist system wide parameters and states&lt;br /&gt;
as&lt;br /&gt;
described in the project outline document.&lt;br /&gt;
In this implementation, access to parameters and states is mediated&lt;br /&gt;
through&lt;br /&gt;
a class &amp;lt;tt&amp;gt;Environment&amp;lt;/tt&amp;gt;. This class provides functions for&lt;br /&gt;
convenient access&lt;br /&gt;
to parameters and states, and transparently handles a number of error&lt;br /&gt;
conditions&lt;br /&gt;
that might occur.&lt;br /&gt;
The services provided by the &amp;lt;tt&amp;gt;Environment&amp;lt;/tt&amp;gt; class interface are&lt;br /&gt;
available&lt;br /&gt;
to all classes that inherit from it. For &amp;lt;tt&amp;gt;GenericFilter&amp;lt;/tt&amp;gt;&lt;br /&gt;
descendants, this&lt;br /&gt;
is automatically the case; for other classes, you need to explicitly&lt;br /&gt;
state&lt;br /&gt;
the inheritance as in&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;quot;Environment.h&amp;quot;&lt;br /&gt;
...&lt;br /&gt;
MyClass : private Environment&lt;br /&gt;
{&lt;br /&gt;
  ...&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Access to Parameters and States==&lt;br /&gt;
From any code inside &amp;lt;tt&amp;gt;MyClass&amp;lt;/tt&amp;gt;, you may then read or set&lt;br /&gt;
parameter and state values simply by writing&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
int numberOfItems = Parameter( &amp;quot;NumberOfItems&amp;quot; );&lt;br /&gt;
float listValue = Parameter( &amp;quot;ListParam&amp;quot; )( index );&lt;br /&gt;
float matrixValue = Parameter( &amp;quot;MatrixParam&amp;quot; )( index1, index2 );&lt;br /&gt;
float nestedMatrixValue&lt;br /&gt;
  = Parameter( &amp;quot;NestedMatrices&amp;quot; )( index1, index2 )( index3, index4 );&lt;br /&gt;
short feedbackState = State( &amp;quot;Feedback&amp;quot; );&lt;br /&gt;
State( &amp;quot;Feedback&amp;quot; ) = 0;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
If you try accessing a parameter or state that does not exist, an&lt;br /&gt;
appropriate&lt;br /&gt;
error message will be sent to &amp;lt;tt&amp;gt;bcierr&amp;lt;/tt&amp;gt;, so you don&#039;t need to&lt;br /&gt;
handle&lt;br /&gt;
this type of error explicitly.&lt;br /&gt;
For a greater independence between modules, it is sometimes desirable&lt;br /&gt;
to&lt;br /&gt;
read a parameter or state if it exists, and use a default value&lt;br /&gt;
otherwise.&lt;br /&gt;
You achieve this by writing &amp;lt;pre&amp;gt;int numberOfItems = OptionalParameter( defaultValue, &amp;quot;NumberOfItems&amp;quot; );&lt;br /&gt;
short itiState = OptionalState( 0, &amp;quot;IntertrialInterval&amp;quot; );&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Working around Borland VCL Inheritance Restrictions==&lt;br /&gt;
Due to some non-standard conventions in Borland&#039;s VCL library, you&lt;br /&gt;
cannot create a VCL class such as a &amp;lt;tt&amp;gt;TForm&amp;lt;/tt&amp;gt; descendant that&lt;br /&gt;
also&lt;br /&gt;
inherits from &amp;lt;tt&amp;gt;Environment&amp;lt;/tt&amp;gt; -- the compiler will report an&lt;br /&gt;
error&lt;br /&gt;
if you try.&lt;br /&gt;
As a work-around, you might declare an &amp;lt;tt&amp;gt;Environment&amp;lt;/tt&amp;gt; subclass&lt;br /&gt;
&#039;&#039;inside&#039;&#039;  your VCL &amp;lt;tt&amp;gt;TForm&amp;lt;/tt&amp;gt; child declaration,&lt;br /&gt;
and create a single instance &amp;lt;tt&amp;gt;mEnv&amp;lt;/tt&amp;gt; of this subclass as a&lt;br /&gt;
member&lt;br /&gt;
of your class, using it to access the &amp;lt;tt&amp;gt;Environment&amp;lt;/tt&amp;gt; functions&lt;br /&gt;
as in&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
MyForm : public TForm&lt;br /&gt;
{&lt;br /&gt;
  ...&lt;br /&gt;
  private:&lt;br /&gt;
    class MyFormEnvironment : private Environment&lt;br /&gt;
    {&lt;br /&gt;
      public:&lt;br /&gt;
        MyFormEnvironment( MyForm&amp;amp; parent );&lt;br /&gt;
        void Preflight() const;&lt;br /&gt;
        void Initialize();&lt;br /&gt;
    } mEnv;&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
...&lt;br /&gt;
&lt;br /&gt;
MyForm::MyFormEnvironment( MyForm&amp;amp; parent )&lt;br /&gt;
: mParent( parent )&lt;br /&gt;
{&lt;br /&gt;
  BEGIN_PARAMETER_DEFINITIONS&lt;br /&gt;
    &amp;quot;UsrTask int MyParam= 1 1 0 5 // my parameter&amp;quot;,&lt;br /&gt;
  END_PARAMETER_DEFINITIONS&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
...&lt;br /&gt;
&lt;br /&gt;
void&lt;br /&gt;
MyForm::Initialize()&lt;br /&gt;
{&lt;br /&gt;
  mEnv.Initialize();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void&lt;br /&gt;
MyForm::MyFormEnvironment::Initialize()&lt;br /&gt;
{&lt;br /&gt;
  mParent.mMyParam = Parameter( &amp;quot;MyParam&amp;quot; );&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
This should work in situations where your code&#039;s class model is&lt;br /&gt;
centered around&lt;br /&gt;
VCL form classes.&lt;br /&gt;
When writing new code, you might consider basing your class model on&lt;br /&gt;
functionality, and use VCL forms merely for input and output --&lt;br /&gt;
instantiating,&lt;br /&gt;
populating, and deleting them as you need them, such that the BCI2000&lt;br /&gt;
&amp;lt;tt&amp;gt;Environment&amp;lt;/tt&amp;gt; interfacing is done from your own classes,&lt;br /&gt;
independently&lt;br /&gt;
of the VCL&#039;s special requirements.&lt;br /&gt;
-----&lt;br /&gt;
See also: [[Error Handling]]&lt;/div&gt;</summary>
		<author><name>Atennissen</name></author>
	</entry>
	<entry>
		<id>https://www.bci2000.org/mediawiki/index.php?title=Technical_Reference:Parameter_File&amp;diff=1745</id>
		<title>Technical Reference:Parameter File</title>
		<link rel="alternate" type="text/html" href="https://www.bci2000.org/mediawiki/index.php?title=Technical_Reference:Parameter_File&amp;diff=1745"/>
		<updated>2007-05-07T16:35:57Z</updated>

		<summary type="html">&lt;p&gt;Atennissen: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;In BCI2000, [[Parameter Definition|parameters]] are variables describing system configuration.&lt;br /&gt;
Parameter files (extension &amp;lt;tt&amp;gt;.prm&amp;lt;/tt&amp;gt;) contain collections of parameter values.&lt;br /&gt;
As each parameter file may contain a subset of all parameters available in a BCI2000 system, it is possible to factor out individual aspects of configuration into separate parameter files (&amp;quot;fragments&amp;quot;) which may then be combined together as needed.&lt;br /&gt;
&lt;br /&gt;
Parameters have a human readable representation as a [[Parameter Definition]] line.&lt;br /&gt;
Parameter files represent collections of parameter values in the form of sequences of such definition lines, separated by Windows/DOS line separator codes.&lt;br /&gt;
&lt;br /&gt;
Thus, parameter files may be modified using a standard text editor (although it will generally be easier to use the parameter editor dialog of the operator module). &lt;br /&gt;
----&lt;br /&gt;
See also: [[Data file]]&lt;/div&gt;</summary>
		<author><name>Atennissen</name></author>
	</entry>
	<entry>
		<id>https://www.bci2000.org/mediawiki/index.php?title=Mu_Rhythm_Off-line_Analysis_Tutorial&amp;diff=1744</id>
		<title>Mu Rhythm Off-line Analysis Tutorial</title>
		<link rel="alternate" type="text/html" href="https://www.bci2000.org/mediawiki/index.php?title=Mu_Rhythm_Off-line_Analysis_Tutorial&amp;diff=1744"/>
		<updated>2007-05-07T16:34:18Z</updated>

		<summary type="html">&lt;p&gt;Atennissen: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Starting an analysis session ==&lt;br /&gt;
&lt;br /&gt;
Every recording session has its own history. It is very difficult to say in advance what might happen during the recording. So we will assume that everything was perfect (the subject collaborated, no channel went lost, etc); later on we will consider the main causes of contamination, how to recognize it and what to do.&lt;br /&gt;
&lt;br /&gt;
If the recording session run smoothly, in the folder &#039;&#039;\TestData\Data\Mu&#039;&#039; you should now have two files named &#039;&#039;ALFAS006R01.dat&#039;&#039; and &#039;&#039;ALFAS006R02.dat&#039;&#039;, corresponding to two of the eight runs usually recorded, respectively.&lt;br /&gt;
&lt;br /&gt;
Before you start the analysis you should locate on your hard disk the correct montage file. This is a file that describes the list of channels that were acquired. In this tutorial we will use &#039;&#039;Complete_Montage(suggested choice).mmf&#039;&#039;, which is located in the folder &#039;&#039;\TestData\Montage&#039;&#039;. If you need to edit the *.mmf file, check its data format.&lt;br /&gt;
&amp;lt; the of performances optimize that parameters try will we then online; performed BCI2000 analyses same off-line replicate to first&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Opening files with Mario ==&lt;br /&gt;
&lt;br /&gt;
After having run mario.exe, press &amp;quot;Select Data Files&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
[[Image:Mu Rhy5.jpg]]&lt;br /&gt;
&lt;br /&gt;
A dialog window will ask you to select the dat files. You can either select a single data file, or select multiple files. This time, we will select all files in the dataset.&lt;br /&gt;
&lt;br /&gt;
A green box will surround the Raw Data box in the main window.&lt;br /&gt;
&lt;br /&gt;
As an optional (but recommended) operation, push the LOAD MONTAGE button and choose the mmf file. This will allow you to see the labels of each channel the following steps, and to allow to apply spatial filters that depend on the electrode position.&lt;br /&gt;
&lt;br /&gt;
At least you can load an additional parameters file according to different choices from those carried out during the experimentation.&lt;br /&gt;
&lt;br /&gt;
At this point, you can check that Mu is selected in the Analysis menu (indicating that a Mu dataset has been recognized) and push the LOAD DATA button to confirm your choices. This will enable the EDIT CHANNEL LIST button you can use to select the channels you want to include in your analysis.&lt;br /&gt;
&lt;br /&gt;
== Selecting Channels ==&lt;br /&gt;
&lt;br /&gt;
Pushing the the EDIT CHANNEL LIST button, two forms will show you the channels list (valids&#039; and not-valids&#039; one) and an image reassuming valid channels and their location.&lt;br /&gt;
&lt;br /&gt;
Clicking on Add and Remove buttons you can move whichever channel from one list to the other enabling or disabling it.&lt;br /&gt;
&lt;br /&gt;
== Selecting the Spatial Filter ==&lt;br /&gt;
&lt;br /&gt;
Coming back to main window, you can therefore choose which filter to apply for your elaborations, selecting it between the possible supplied solutions.&lt;br /&gt;
&lt;br /&gt;
You can choose from:&lt;br /&gt;
&lt;br /&gt;
:*RAW&lt;br /&gt;
:*CAR&lt;br /&gt;
:*Large Laplacian&lt;br /&gt;
:*Small Laplacian&lt;br /&gt;
&lt;br /&gt;
Common Average Reference (CAR) will be fine for most the situations.&lt;br /&gt;
&lt;br /&gt;
We hope to release soon an user defined solution for any custom analysis.&lt;br /&gt;
&lt;br /&gt;
== Feature Extraction Analysis ==&lt;br /&gt;
&lt;br /&gt;
The Analysis field in the Feature Extraction panel will appear automatically according to loaded files while the Feature Extractor field shows currently the only possible choice.&lt;br /&gt;
&lt;br /&gt;
You can view/edit analysis details by pushing &amp;quot;Set Analysis Details&amp;quot; and &amp;quot;Set F.E. parameters&amp;quot;&lt;br /&gt;
&lt;br /&gt;
This second form reports all the settings for the parametric (autoregressive) spectral estimation stage. Most of the values are set after the corresponding values used on-line (see BCI2000 setup for Mu). With settings as the ones reported in figure, the analysis software will:&lt;br /&gt;
&lt;br /&gt;
:*data recorded at 200 Hz sampling rate;&lt;br /&gt;
:* remove the mean value;&lt;br /&gt;
:* sample the spectrum at points starting from 0 Hz to 60 Hz, every 0.2 Hz.;&lt;br /&gt;
:* Identify an auroregressive model of order 16;&lt;br /&gt;
:* average these values into 2 Hz wide bins;&lt;br /&gt;
:* take a 1 s long epoch of data.&lt;br /&gt;
&lt;br /&gt;
You can modify these settings according to your aims. Changing the model order, for instance, brings sometimes to interesting results. Remember though that in the online version, spectral estimation is performed in epochs as short as 200 ms (i.e. 40 samples, at 200 Hz sampling rate), so you should avoid using model order higher than half the samples available in the epoch.&lt;br /&gt;
When you are done, remember to confirm your choices by pushing DONE. It will make the program accept changes.&lt;br /&gt;
&lt;br /&gt;
Moreover, a button in the Spectral Extimation frame allows you to revert the values to the original.&lt;br /&gt;
&lt;br /&gt;
Altogether you have to specify:&lt;br /&gt;
&lt;br /&gt;
:* which data (in each trial) you want to take into account. Mu will only use the part of the trial when the cursor is visible, while MuExtended will take into account all the period when the target is visible. To learn more, see section D2Box Application States ;&lt;br /&gt;
:* If you have made an artifact rejection (or noted on the run sheet during the acquisition which trials contain artifacts), you can instruct the software not to use them;&lt;br /&gt;
:* Finally, you must decide how the software must extract EEG epochs from the continuous data.&lt;br /&gt;
The epochs can be partially overlapped. This attenuates the data loss in case the length of a trial is not a multiple of the length of an epoch.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The percentage of overlap can be set both in Mario GUI and in any batch script. It&#039;s equal to the value of the &#039;&#039;MU_params.overlapping&#039;&#039; variable and the corresponding GUI field can be found by pressing &#039;&#039;Set Analysis Details&#039;&#039; on MARIO main form.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
At this point you can start the analysis by pressing the Evaluate and Plot button.&lt;br /&gt;
&lt;br /&gt;
[[Image:Mu Rhy8.jpg]]&lt;br /&gt;
&lt;br /&gt;
== View results ==&lt;br /&gt;
&lt;br /&gt;
The first figure that appears is the R-square matrix (channels x frequency bins)&lt;br /&gt;
=== R-square matrix ===&lt;br /&gt;
&lt;br /&gt;
The r-square matrix highlights the most relevant spectral features for the separation of the two classes of EEG - Cursor Up (target 1) and Cursor Down (target 2).&lt;br /&gt;
&lt;br /&gt;
[[Image:Mu Rhy8.jpg]]&lt;br /&gt;
&lt;br /&gt;
Each row of the matrix is related to a single channel, while a column represents a frequency bin (labeled with its central frequency). The color codes the statistical significance of the difference between the two kind of evoked potentials.&lt;br /&gt;
&lt;br /&gt;
Thus a red color would mean that, on that channel and for that frequency, the &amp;quot;Up&amp;quot; EEG is significantly synchronized with respect to &amp;quot;Down&amp;quot; EEG.&lt;br /&gt;
&lt;br /&gt;
Clicking on a cell of the matrix will open two more windows:&lt;br /&gt;
&lt;br /&gt;
* Power spectral distribution of the selected channel&lt;br /&gt;
* Topographic maps at the selected frequency.&lt;br /&gt;
&lt;br /&gt;
You can choose whether to overwrite or to put the most recently evoked figures beside the previous one. Two sets of waveform/topography figures are available, and are linked to the click of the left, the central or right mouse button.&lt;br /&gt;
&amp;lt;b&amp;gt;Left Button&amp;lt;/b&amp;gt; will create/overwrite a first figure, &amp;lt;b&amp;gt;Right Button&amp;lt;/b&amp;gt; will do the same on a second figure, the &amp;lt;b&amp;gt;Central Button&amp;lt;/b&amp;gt; will always open a new plot.&lt;br /&gt;
&lt;br /&gt;
=== Power Spectra and Topographic Plots ===&lt;br /&gt;
&lt;br /&gt;
In the lower panel you can find the spectral density of power for both classes of EEG. Blue line refers to &amp;quot;Up&amp;quot; condition, while Red line to &amp;quot;Down&amp;quot;.&lt;br /&gt;
We can see that at the vertex the &amp;quot;Down&amp;quot; condition is generally more synchronized than the &amp;quot;Up&amp;quot;, with maximal difference in the beta band, consistently with what is shown by the R-square matrix.  The proportinality between spectral differences and R-square is anyway rough, since r-square is sensitive to the dispersion (variance) of single trials; thus, small differences between spectra could bring to a high r-square, if they were very reproducible.&lt;br /&gt;
&lt;br /&gt;
The peak around 50 Hz is due to mains disturbance; this also allows to appreciate the leakage introduced by the spectral estimation.&lt;br /&gt;
&lt;br /&gt;
[[Image:Mu_Rhy9.jpg]]&lt;br /&gt;
&lt;br /&gt;
Over the spectral graph, a topografic plot shows the scalp distribution of the r-square.&lt;br /&gt;
&lt;br /&gt;
The color coding is the same as the r-square matrix figure, and values on each channel are interpolated to create a continuous bidimensional map. The higher the number of electrodes, the more accurate is the map. The number of channels shown on the scalp may not coincide with the whole number of electrodes in case of a Surface Laplacian spatial filtering, since in that case the value of the laplacian is not computed on the border channels.&lt;br /&gt;
Interpretation of the results&lt;br /&gt;
&lt;br /&gt;
The first step in the preliminary analysis of P300 BCI data is to find the absolute maximum of r-square. This simple statement must be mediated with a proper knowledge of physiological phenomena. In fact, we do not expect any sensorimotor activity at 3 Hz, so if the absolute maximum is at that frequency, you must suspect that it is actually an artifact. The same holds if the spatial localization of the peak is far away from the centro-parietal electrodes.&lt;br /&gt;
&lt;br /&gt;
From a practical point of view, it is not important now to understand the reasons different component that explain the desynchrinization peak on Cz at 17 Hz, as far as we are confident that this component is stable enough to be exploitable during the next session to control the cursor.&lt;br /&gt;
&lt;br /&gt;
The absolute value of R-square is mathematically bound to lie in the interval between 0 and 1. Values above 0.4 allow a rate of missed target in the order of a few percent. Values around 0.1 are promising. Values below 0.03 are possibly due to random fluctuations. All the previous figures are referred to analyses made on 240 trials.&lt;br /&gt;
&#039;&#039;&amp;lt;b&amp;gt;Beware of artifacts!&amp;lt;/b&amp;gt;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
During the acquisition, you should be particularly careful to avoid artifacts. While EOG and blink artifacts are confined to very low frequencies, EMG artifacts are mostly on the beta band and could largely overlap with the frequency band that characterize the mu rhythm.&lt;br /&gt;
&lt;br /&gt;
If contaminated data was acquired, then you have two problems:&lt;br /&gt;
&lt;br /&gt;
:* Realize that EMG is superimposed to data&lt;br /&gt;
:* Distinguish between spectral modulation introduced by EEG and by EMG &lt;br /&gt;
&lt;br /&gt;
The first task is not as trivial as it might appear. If you did not acquire the data yourself (or even if you did) you might complete the analysis procedure without giving a single glance to the raw data. So you must be particularly careful when you analyze the R-square maps, and always wonder whether the peak you are seeing might be due to an artifact.&lt;br /&gt;
&lt;br /&gt;
Discriminant features between EEG and EMG are both in the frequency distribution and in the spatial distribution.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
EMG that strongly affects the recordings is mostly generated by muscles at the forehead or close to the ears/jaws. Thus their spatial distribution is such that the most responsive channel is one of those at the border of the montage. Of course, due to volume conduction, the effects can be seen even on electrodes on the opposite part of the montage, but they show a degrading pattern.&lt;br /&gt;
On the other hand, a peak that shows its maximum on a central channel, can hardly be generated by a muscle or by other non-cephalic source.&lt;br /&gt;
&lt;br /&gt;
The spectrum of EEG is mainly concentrated in the alpha band, with a possible flatter and lower peak in beta. With the exception of the beta peak/plateau, the EEG spectrum decreases almost linearly (if measured in dB) after 12 Hz.&lt;br /&gt;
On the other hand, EMG spectrum becomes significant at about 20 Hz and is still very high at the highest frequencies we usually analyze (60 Hz). A spectrum with a pattern more similar to the latter, must induce the suspect that non-EEG activity is present in the data.&lt;br /&gt;
&lt;br /&gt;
==Improving the analysis==&lt;br /&gt;
&lt;br /&gt;
The first cause of an unsuccessful analysis is a poor quality of the recording. For this reason it is highly recommended that, at least for the first experiments, the subject be highly motivated and cooperative. If this is the case, data of low quality are usually present in one or a few runs. And if the experimenter is careful enough, he/she should have noted down the occurrence of strong artifacts on the run sheet.&lt;br /&gt;
In this hypothesis, the following step is to repeat an unsatisfactory data analysis after having excluded the (putative) bad runs.&lt;br /&gt;
To do this, just go back to the file selection dialog, choose LOAD Data again and load only the runs that you believe are clean. The number of runs should not be too low (as a rule of thumb, the data set should contain at least 100 trials), otherwise the r-square statistical analysis would loose sensitivity.&lt;br /&gt;
&lt;br /&gt;
== Analyzing the Screening ==&lt;br /&gt;
&lt;br /&gt;
The screening experiment is not different from a regular training session, from the point of view of data format. You will have four sets (horizontal movement, horizontal imagination, vertical movement, and vertical imagination) of three runs, containing EEG acquired in two conditions (up and down, or left and right).&lt;br /&gt;
&lt;br /&gt;
Start analyzing the vertical movement execution, and mark a few possible responsive features. The analysis on vertical movement imagination should confirm (though with a lower R-square) those that are actually related to sensorimotor cognitive states.&lt;br /&gt;
&lt;br /&gt;
In the hypothesis that no reliable responsive EEG feature is found, the analysis can be repeated on the horizontal dataset.&lt;br /&gt;
&lt;br /&gt;
If both the vertical and horizontal dataset show responsive features, and these are different, the subject should be trained for some session on the vertical training until he/she decreases the false positive below 10%; at that point the training of the horizontal modulation can begin, with the aim that at a certain point the subject can control both the vertical and the horizontal simultaneously in a two-dimensional task.&lt;br /&gt;
&lt;br /&gt;
==Conclusions==&lt;br /&gt;
&lt;br /&gt;
If you are confident that you have found a significant difference between conditions that is due to EEG rather than an artifact, and that reflects a cognitive process that is likely to be reproduced (or even enhanced with training) in the next session, you have reached your goal.&lt;br /&gt;
Next time the same subject practices with the D2Box Application, you will have to change the MUD matrix so that it reflects the feature that you just outlined.&lt;br /&gt;
&lt;br /&gt;
==Troubleshooting==&lt;br /&gt;
&lt;br /&gt;
Some OpenGL drivers may sometimes show defective figures like the following:&lt;br /&gt;
&lt;br /&gt;
[[Image:Defective.jpg]]&lt;br /&gt;
&lt;br /&gt;
Matlab customers can get around this problem using this simple procedure:&lt;br /&gt;
:* Select the defective figure window&lt;br /&gt;
:* Go to the Matlab Command Window&lt;br /&gt;
:* Execute one of the following command line:&lt;br /&gt;
:**set(gcf, &#039;Renderer&#039;, &#039;Painters&#039;);&lt;br /&gt;
:**set(gcf, &#039;Renderer&#039;, &#039;zbuffer&#039;)&lt;br /&gt;
&lt;br /&gt;
The figure will be a plot using a different renderer (Painters or zBuffer).&lt;/div&gt;</summary>
		<author><name>Atennissen</name></author>
	</entry>
	<entry>
		<id>https://www.bci2000.org/mediawiki/index.php?title=MARIO_Technical_Documentation&amp;diff=1742</id>
		<title>MARIO Technical Documentation</title>
		<link rel="alternate" type="text/html" href="https://www.bci2000.org/mediawiki/index.php?title=MARIO_Technical_Documentation&amp;diff=1742"/>
		<updated>2007-05-07T16:15:22Z</updated>

		<summary type="html">&lt;p&gt;Atennissen: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==MARIO architecture==&lt;br /&gt;
MARIO is an off-line analysis application developed in MATLAB 7.0.2. It is now modular, object-oriented and can be easily integrated with any other software for data analysis and visualization.&lt;br /&gt;
It can be used in Mu and P300 analyses and allows two kinds of use: users can simply fill the forms of a graphical interface making any choice with a click of its mouse, run a ready-made script or, at least, write up their own scripts according to their needs.&lt;br /&gt;
This set of interfaces allows a wide range of possibilities for a wide range of different analyses.&lt;br /&gt;
&lt;br /&gt;
Internally, the application is composed of 6 main functional modules, each one connected in cascade as in the list below:&lt;br /&gt;
&lt;br /&gt;
*Data import&lt;br /&gt;
*Signal Conditioning&lt;br /&gt;
*Feature Extraction&lt;br /&gt;
*Spectral Extimation&lt;br /&gt;
*Statistical Analysis&lt;br /&gt;
*Visualization&lt;br /&gt;
&lt;br /&gt;
[[Image:arch_blocks.jpg]]&lt;br /&gt;
&lt;br /&gt;
All these modules are hidden in the graphical user interface but they can be distinguished in the batch scripts. Each one of them can be easily replaced with an improved version, a custom version or a different analysis.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Image:Graph.png|thumb|left|Graph of modules]] &lt;br /&gt;
Here you can see a &amp;lt;b&amp;gt;simplified version of the functions graph with their relationships (click to enlarge). &amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Data Import Module==&lt;br /&gt;
&lt;br /&gt;
Any script must have a first module to load data that theuser wants to analyze.&lt;br /&gt;
There are 3 main types of files containing different groups of information:&lt;br /&gt;
&lt;br /&gt;
*Data files (.dat/.mat)&lt;br /&gt;
*Montage files (.mmf)&lt;br /&gt;
*External Parameter files (.prm) – optional&lt;br /&gt;
&lt;br /&gt;
The data files contain all the data of the BCI session (Mu or P300).&lt;br /&gt;
These data are saved in different files, one for each run, containing 29 trials.&lt;br /&gt;
Internally any file is divided in two main parts: the first part (file header) includes all parameters set by the operator  during the on-line experimentation; the second part contains the EEG signal recorded by the whole set of electrodes on the EEG cap.&lt;br /&gt;
A special function allows at least to load data from a Matlab file (.mat).&lt;br /&gt;
&lt;br /&gt;
The montage file stores information about the electrode position on the scalp. It can be &lt;br /&gt;
drawn up writing in different sections divided by labels:&lt;br /&gt;
&lt;br /&gt;
#a synthetic name&lt;br /&gt;
#the channel labels&lt;br /&gt;
#a valid channels list&lt;br /&gt;
#the laplacian grid&lt;br /&gt;
#the 3-dimensional spatial coordinates of all the electrodes (this section is optional)&lt;br /&gt;
&lt;br /&gt;
This information is divided by labels and can be written in the Montage file without a predefined order.&lt;br /&gt;
&lt;br /&gt;
At least, user can import data from an additional data file, a parameters file, that can be used if he want to replace one or more parameters from the BCI2000 ones. In this chance is enough  to copy  and paste in a new prm file the header string selected, changing its value.&lt;br /&gt;
&lt;br /&gt;
This module is clearly the same for Mu and P300 Analysis.&lt;br /&gt;
&lt;br /&gt;
==Data Conditioning Module==&lt;br /&gt;
&lt;br /&gt;
The MARIO v.2.0 Data Conditioning module allows users to select from a wide range of spatial filters such as to include custom filter in user data analysis. So the operator can identify which channels or set of channels can give better results at the end of the statistical analysis.&lt;br /&gt;
&lt;br /&gt;
For a Mu analysis, the user can select from four different spatial filter algorithms:&lt;br /&gt;
&lt;br /&gt;
*RAW&lt;br /&gt;
*CAR (Common Average Reference)&lt;br /&gt;
*SMALL LAP&lt;br /&gt;
*LARGE LAP&lt;br /&gt;
&lt;br /&gt;
The first one (RAW) does not use a filter and analyzes raw recorded data. Every other selection agrees with the choice to employ any spatial filter. An user defined analysis will be available on further versions of MARIO.&lt;br /&gt;
&lt;br /&gt;
The Data Conditioning module also allows the user to compile/modify a list of valid channels on which any analysis will be conduced.&lt;br /&gt;
&lt;br /&gt;
P300 Analysis can now use only two of the above spatial filters: the RAW filter and the CAR one. Any other selection will report an unhandled error.&lt;br /&gt;
&lt;br /&gt;
==Feature Extraction Module==&lt;br /&gt;
&lt;br /&gt;
Feature extraction is one of the most important stages of elaboration; it affects any further analysis.&lt;br /&gt;
&lt;br /&gt;
In a Mu rhythm analysis, any feature can be obtained arranging some of the 12 BCI2000 states.&lt;br /&gt;
User can now make a choice between two predefined analysis, a simple Mu analysis or an Extended version of the same. The first analysis considers any sample recorded between the cursor appearance on the screen and the end of the trial (when the cursor reaches the right side of the screen).&lt;br /&gt;
The MuExteded analysis instead considers any sample recorded since the target appearance (during the first subset of data subject didn’t have any feedback) till the end of trial.&lt;br /&gt;
In both choices, the statistical analysis will be conduced between two classes of data: the EEG activity recorded while moving up the cursor  (target UP) versus the EEG activity recorded while moving down the cursor (target DOWN).&lt;br /&gt;
Anyone of these choice will produce different R&amp;lt;sup&amp;gt;2&amp;lt;/sup&amp;gt; values between the corresponding features of the two classes&lt;br /&gt;
&lt;br /&gt;
For a P300 Analysis the classes compared are only two and automatically set as frequent events and rare events.&lt;br /&gt;
&lt;br /&gt;
==Spectral Extimation Module &#039;&#039;(just for Mu rhythm analysis)&#039;&#039;==&lt;br /&gt;
&lt;br /&gt;
During this step, the program evaluates the spectrum of recorded data; any further analysis will be done on it.&lt;br /&gt;
To do that, EEG signal is divided into equal length epoch (that can be distinct or overlapped of a percentage of overlap that user can set by Graphical User Interface or script) and a spectrum value is evaluated for anyone of these.&lt;br /&gt;
&lt;br /&gt;
At the end of this process, a 3 dimensional matrix (bin × channel × epoch) joined with the one (channel × sample) compiled during a BCI2000 recording session and read by the data import module will be produced.&lt;br /&gt;
&lt;br /&gt;
The algorithm employed to estimate the signal spectrum is the MEM (the same used on-line by BCI2000).&lt;br /&gt;
&lt;br /&gt;
Apart from the percentage of overlap MARIO allows the user to modify the values of:&lt;br /&gt;
&lt;br /&gt;
#Sampling frequency of recorded data;&lt;br /&gt;
#Spatial resolution (delta);&lt;br /&gt;
#Detrending order (Mean or Linear);&lt;br /&gt;
#AR model order;&lt;br /&gt;
#Low pass filter frequency;&lt;br /&gt;
#High pass filter frequency;&lt;br /&gt;
#Filter bandwidth;&lt;br /&gt;
#Epoch length;&lt;br /&gt;
#Overlap percentage.&lt;br /&gt;
&lt;br /&gt;
MARIO v2.0 also computes a virtual states matrix strictly joined with signal one and derived as a arrangement of the BCI2000 states. These states label spectrum samples as valid or not and as belonging to one class or another.&lt;br /&gt;
&lt;br /&gt;
Since that, every further analysis on BCI2000 data can be done.&lt;br /&gt;
&lt;br /&gt;
==Statistical Analysis Module==&lt;br /&gt;
&lt;br /&gt;
At least, a statistical analysis (at present the R&amp;lt;sup&amp;gt;2&amp;lt;/sup&amp;gt;)  is employed to distinguish between the class of a BCI2000 task in any trial.&lt;br /&gt;
&lt;br /&gt;
MARIO uses a module that computes the R&amp;lt;sup&amp;gt;2&amp;lt;/sup&amp;gt; value between two classes that can be TargetUP and TargetDOWN for a Mu rhythm analysis, such as frequent and rare events for a P300 analysis. These data are taken from the spectra matrix (Mu analysis) or from the samples one (P300 analysis) and the regressor vector is yield from BCI2000 states.&lt;br /&gt;
	&lt;br /&gt;
At the end of this analysis, the real index (in a range between -1 and 1) produced is the R&amp;lt;sup&amp;gt;2&amp;lt;/sup&amp;gt; value multiplied by R&amp;lt;sup&amp;gt;2&amp;lt;/sup&amp;gt; sign. If the R&amp;lt;sup&amp;gt;2&amp;lt;/sup&amp;gt; value is near 1 it means there is an high separability between classes and high performances. If instead its value is near 0, it’s difficult to distinguish a class from another, and it means low performances.&lt;br /&gt;
&lt;br /&gt;
==Visualization Module==&lt;br /&gt;
&lt;br /&gt;
Mario offers a wide set of visualization graphs that can be combined to have a complete visualization of produced data.&lt;br /&gt;
For a Mu rhythm analysis user can request to visualize:&lt;br /&gt;
&lt;br /&gt;
#a trajectory plot shows the cursor position for any sample in a  trial BCI2000 as user saw it on-line;&lt;br /&gt;
#a matrix (channel × bin) shows as a colour tint the R&amp;lt;sup&amp;gt;2&amp;lt;/sup&amp;gt; value of any feature. A colorbar shows the colour range between -1 and 1;&lt;br /&gt;
#Another panel shows a detail of the previous matrix. The upper topographic plot shows the R&amp;lt;sup&amp;gt;2&amp;lt;/sup&amp;gt; value for any channel in the selected bin of frequencies; the lower one is the spectrum of the selected channel for all the frequencies.&lt;br /&gt;
&lt;br /&gt;
For a P300 analysis user can choose between:&lt;br /&gt;
&lt;br /&gt;
#A R&amp;lt;sup&amp;gt;2&amp;lt;/sup&amp;gt; matrix&lt;br /&gt;
#An amplitude waveform graph&lt;br /&gt;
#A topographic plot&lt;br /&gt;
#An ERP response graph&lt;br /&gt;
#A string prediction form.&lt;br /&gt;
&lt;br /&gt;
All these result visualizations can be easily included in any of user scripts for custom analysis.&lt;/div&gt;</summary>
		<author><name>Atennissen</name></author>
	</entry>
	<entry>
		<id>https://www.bci2000.org/mediawiki/index.php?title=Programming_Reference:Cpp_Coding_Style&amp;diff=1741</id>
		<title>Programming Reference:Cpp Coding Style</title>
		<link rel="alternate" type="text/html" href="https://www.bci2000.org/mediawiki/index.php?title=Programming_Reference:Cpp_Coding_Style&amp;diff=1741"/>
		<updated>2007-05-07T15:49:21Z</updated>

		<summary type="html">&lt;p&gt;Atennissen: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Line Formatting ==&lt;br /&gt;
* No tab characters (please configure your editor to insert spaces instead).&lt;br /&gt;
* Indentation in steps of 2 or 3 space characters.&lt;br /&gt;
* Opening braces have their own line, aligned with the previous line; corresponding closing braces are placed on their own lines, at the same character position as the opening brace.&lt;br /&gt;
* For function definitions, return types appear on their own line, such that the function name is first in its line.&lt;br /&gt;
&lt;br /&gt;
== Naming ==&lt;br /&gt;
* &#039;&#039;&#039;ALL_UPPERCASE_NAMES&#039;&#039;&#039; are reserved for preprocessor macros.&lt;br /&gt;
* &#039;&#039;&#039;CamelCase&#039;&#039;&#039; (uppercase letters inside words) is used to indicate word boundaries.&lt;br /&gt;
* Class names and namespaces begin with uppercase letters: &#039;&#039;&#039;MyNameSpace&#039;&#039;&#039;, &#039;&#039;&#039;TheClass&#039;&#039;&#039;.&lt;br /&gt;
* Local variables and function arguments begin with lowercase letters: &#039;&#039;&#039;theCounter&#039;&#039;&#039;, &#039;&#039;&#039;inSomeInput&#039;&#039;&#039;.&lt;br /&gt;
* Data members of true classes are private, and accessed via &#039;&#039;&#039;Accessor Functions&#039;&#039;&#039;.&lt;br /&gt;
** &#039;&#039;&#039;Setters&#039;&#039;&#039; use the prefix &amp;quot;Set&amp;quot; followed by the property&#039;s name, or directly the name of the property: &#039;&#039;&#039;SetValue()&#039;&#039;&#039;. Setter functions should also return a non-const reference to the data object itself rather than &#039;&#039;&#039;void&#039;&#039;&#039;, this allows for chaining as in&amp;lt;br /&amp;gt;&amp;lt;code&amp;gt;float result = MyComputation().SetOrder( 5 ).SetDepth( 10 ).EvaluateAt( 4 );&amp;lt;/code&amp;gt;&lt;br /&gt;
** &#039;&#039;&#039;Getters&#039;&#039;&#039; use the name of the property: &#039;&#039;&#039;Value()&#039;&#039;&#039;. Omitting the &amp;quot;Get&amp;quot; prefix allows the programmer to treat getters and reference accessors identically, as far as read access is concerned.&lt;br /&gt;
** &#039;&#039;&#039;Reference Accessors&#039;&#039;&#039; use the name of the property, and are provided in a doubly &#039;&#039;const&#039;&#039; and a &#039;&#039;non-const&#039;&#039; version. This is important to allow const access from const object references, and to discriminate between read and write accesses (note the &#039;&#039;mPossiblyChanged&#039;&#039; flag):&amp;lt;br /&amp;gt;&amp;lt;code&amp;gt;const int&amp;amp; Value() const { return mValue; }&amp;lt;/code&amp;gt;&amp;lt;br /&amp;gt;&amp;lt;code&amp;gt;int&amp;amp;       Value() { mPossiblyChanged = true; return mValue; }&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Name prefixes ===&lt;br /&gt;
Prefixes should carry information about the scope and usage of a variable but not its type.&lt;br /&gt;
* &#039;&#039;&#039;m&#039;&#039;&#039; for class data members,&lt;br /&gt;
* &#039;&#039;&#039;s&#039;&#039;&#039; for static class members and static variables,&lt;br /&gt;
* &#039;&#039;&#039;g&#039;&#039;&#039; for globals,&lt;br /&gt;
* &#039;&#039;&#039;c&#039;&#039;&#039; for constants,&lt;br /&gt;
* &#039;&#039;&#039;p&#039;&#039;&#039; for pointers,&lt;br /&gt;
* &#039;&#039;&#039;fp&#039;&#039;&#039; for function pointers,&lt;br /&gt;
* &#039;&#039;&#039;in&#039;&#039;&#039; for function input arguments,&lt;br /&gt;
* &#039;&#039;&#039;out&#039;&#039;&#039; for function output arguments,&lt;br /&gt;
* &#039;&#039;&#039;io&#039;&#039;&#039; for function arguments used for input and output.&lt;br /&gt;
&lt;br /&gt;
==Variable Declaration==&lt;br /&gt;
* Always use the narrowest possible scope for a name to avoid side effects.&lt;br /&gt;
* Always initialize variables (at declaration resp. constructor).&lt;br /&gt;
&lt;br /&gt;
==Memory Allocation==&lt;br /&gt;
* Allocate from the &#039;&#039;&#039;stack&#039;&#039;&#039; rather than the &#039;&#039;&#039;heap&#039;&#039;&#039; unless there is a good reason to use the &#039;&#039;&#039;new&#039;&#039;&#039; operator. This avoids memory leaks.&lt;br /&gt;
* Use STL containers rather than allocating arrays with &#039;&#039;&#039;new[]&#039;&#039;&#039;. This eliminates a number of possible errors (initialization, allocation, deallocation).&lt;br /&gt;
&lt;br /&gt;
==Pointers and References==&lt;br /&gt;
* Use references rather than pointers wherever possible.&lt;br /&gt;
&lt;br /&gt;
==Control Flow==&lt;br /&gt;
* Avoid &#039;&#039;&#039;goto&#039;&#039;&#039;, &#039;&#039;&#039;break&#039;&#039;&#039; outside &#039;&#039;&#039;switch&#039;&#039;&#039;-&#039;&#039;&#039;case&#039;&#039;&#039; blocks, and multiple &#039;&#039;&#039;return&#039;&#039;&#039; statements.&lt;br /&gt;
&lt;br /&gt;
== Example Function ==&lt;br /&gt;
&lt;br /&gt;
 void&lt;br /&gt;
 MyClass::MyFunction( const SomeClass&amp;amp; inTheInput, int&amp;amp; outTheResult )&lt;br /&gt;
 {&lt;br /&gt;
   outTheResult = mSomeDataMember;&lt;br /&gt;
   for( int i = 0; i &amp;lt; inTheInput.NumIterations(); ++i )&lt;br /&gt;
   {&lt;br /&gt;
     int k = 4;&lt;br /&gt;
     while( --k &amp;gt; 0 )&lt;br /&gt;
       outTheResult -= k;&lt;br /&gt;
   }&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
[[Category:Development]]&lt;/div&gt;</summary>
		<author><name>Atennissen</name></author>
	</entry>
	<entry>
		<id>https://www.bci2000.org/mediawiki/index.php?title=Programming_Reference:BCI2000_Source_Code&amp;diff=1740</id>
		<title>Programming Reference:BCI2000 Source Code</title>
		<link rel="alternate" type="text/html" href="https://www.bci2000.org/mediawiki/index.php?title=Programming_Reference:BCI2000_Source_Code&amp;diff=1740"/>
		<updated>2007-05-07T15:43:54Z</updated>

		<summary type="html">&lt;p&gt;Atennissen: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Version Management==&lt;br /&gt;
The BCI2000 source code is managed with the help of [http://subversion.tigris.org/ Subversion], an open-source cross-platform versioning tool widely used in various kinds of projects.&lt;br /&gt;
&lt;br /&gt;
Subversion (SVN) uses the HTTP-based [http://en.wikipedia.org/wiki/WebDAV WebDAV] protocol, so even web browsers may be used as clients, although a true SVN client software is required to access all features of the versioning system.&lt;br /&gt;
&lt;br /&gt;
==Browsing the Source Code Repository Online==&lt;br /&gt;
Online viewing, and comparison of different versions of all source code files, is possible with a web browser (http://{{SERVERNAME}}/tracproj/browser).&lt;br /&gt;
(If you get a message about &amp;quot;viewing privileges&amp;quot;, click the &amp;quot;login&amp;quot; link at the top right to log in.)&lt;br /&gt;
&lt;br /&gt;
== TortoiseSVN Client ==&lt;br /&gt;
For Win32 platforms, we recommend [http://www.tortoisesvn.org TortoiseSVN], a comfortable-to-use SVN client integrated into the Explorer shell.&lt;br /&gt;
&lt;br /&gt;
==&amp;quot;How to---&amp;quot; Pages==&lt;br /&gt;
The following pages provide detailed instructions on the setup and use of TortoiseSVN:&lt;br /&gt;
* [[SVN Client Setup]],&lt;br /&gt;
* [[Using TortoiseSVN]].&lt;br /&gt;
&lt;br /&gt;
==Directory Layout==&lt;br /&gt;
The SNV directory layout matches that of the BCI2000 binary distribution:&lt;br /&gt;
&lt;br /&gt;
{|border=&amp;quot;1&amp;quot; cellspacing=&amp;quot;0&amp;quot;&lt;br /&gt;
!batch&lt;br /&gt;
|batch files for online modules&lt;br /&gt;
|-&lt;br /&gt;
!data&lt;br /&gt;
|online data output         &lt;br /&gt;
|-&lt;br /&gt;
!doc&lt;br /&gt;
|information&lt;br /&gt;
|-&lt;br /&gt;
!parms&lt;br /&gt;
|online parameter files&lt;br /&gt;
|-&lt;br /&gt;
!prog&lt;br /&gt;
|online system executables&lt;br /&gt;
|-&lt;br /&gt;
!tools&lt;br /&gt;
|off-line analysis tools&lt;br /&gt;
|-&lt;br /&gt;
!src&lt;br /&gt;
|source code&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Different from the binary distibution, there is a separate directory tree under &#039;&#039;src&#039;&#039;. &lt;br /&gt;
Below &#039;&#039;src&#039;&#039;, there should be no end-user executables, compiled LaTeX files, or pdf files converted from editable formats.&lt;br /&gt;
Rather, their source files should go below &#039;&#039;src&#039;&#039;, and their end-user versions go into either &#039;&#039;prog&#039;&#039;/&#039;&#039;doc&#039;&#039; or the appropriate end-user directory below &#039;&#039;tools&#039;&#039;.&lt;br /&gt;
In all makefiles or project files that are relevant for the binary distribution, the compiled output is directed into the appropriate executable directory (&#039;&#039;prog&#039;&#039; or &#039;&#039;tools/mytool&#039;&#039;).&lt;br /&gt;
&lt;br /&gt;
==Coding Style Guidelines==&lt;br /&gt;
We maintain a loose set of guidelines/rules that is aimed at readability and maintenance efficiency.&lt;br /&gt;
These rules are not obligatory but we ask contributors to consider them before handing in their code.&lt;br /&gt;
* [[Cpp Coding Style]]&lt;br /&gt;
* [[Matlab Coding Style]]&lt;br /&gt;
&lt;br /&gt;
[[Category:Development]]&lt;/div&gt;</summary>
		<author><name>Atennissen</name></author>
	</entry>
	<entry>
		<id>https://www.bci2000.org/mediawiki/index.php?title=Administrators&amp;diff=1738</id>
		<title>Administrators</title>
		<link rel="alternate" type="text/html" href="https://www.bci2000.org/mediawiki/index.php?title=Administrators&amp;diff=1738"/>
		<updated>2007-05-07T15:07:23Z</updated>

		<summary type="html">&lt;p&gt;Atennissen: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Administrator Role==&lt;br /&gt;
Administrators are responsible for setup and maintenance of software and user accounts.&lt;br /&gt;
Although new user accounts may be [[Creating_a_User_Account|created]] by existing users, it may be necessary to contact an administrator to:&lt;br /&gt;
* get more than the default set of user privileges,&lt;br /&gt;
* disable/remove a user account,&lt;br /&gt;
* reset a user&#039;s password.&lt;br /&gt;
&lt;br /&gt;
==Personnel==&lt;br /&gt;
The BCI2000 server is administered by [[Gerwin Schalk]] and [[Jürgen Mellinger]].&lt;br /&gt;
&lt;br /&gt;
[[Category:Roles]] [[Category:Administration]]&lt;/div&gt;</summary>
		<author><name>Atennissen</name></author>
	</entry>
	<entry>
		<id>https://www.bci2000.org/mediawiki/index.php?title=Technical_Reference:BCI2000_Messages&amp;diff=1734</id>
		<title>Technical Reference:BCI2000 Messages</title>
		<link rel="alternate" type="text/html" href="https://www.bci2000.org/mediawiki/index.php?title=Technical_Reference:BCI2000_Messages&amp;diff=1734"/>
		<updated>2007-04-25T16:00:19Z</updated>

		<summary type="html">&lt;p&gt;Atennissen: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Information transferred between BCI2000 modules is packed into messages.&lt;br /&gt;
Each message content corresponds to a BCI2000 data type such as Parameter, State, or Signal, and is wrapped into a layer that allows for routing the message to an appropriate handler.&lt;br /&gt;
BCI2000 data types know how to write themselves to, and read themselves from, a data stream.&lt;br /&gt;
For example, when the wrapper indicates that a message contains a brain signal, the framework code will route the message to a &amp;quot;brain signal&amp;quot; handler function that, in turn, asks a brain signal object to read itself from the message.&lt;br /&gt;
As another example, when the operator module receives a visualization message, the message wrapper layer will not only be used to direct the message to a visualization handler but also to the visualization window to which the message is addressed.&lt;br /&gt;
&lt;br /&gt;
===Protocol Definition===&lt;br /&gt;
Each message starts&lt;br /&gt;
with a one-byte content descriptor and a one-byte descriptor supplement, followed&lt;br /&gt;
by a number that describes the length of the content. (See Figure below)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Image:BCI2000_Messages_MessageProtocol.png|center|thumb|400px|Layout of one message in the protocol.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The element denoted by &amp;quot;length field(2)&amp;quot; was originally a two-byte integer&lt;br /&gt;
field for the content length in little endian format. To allow for messages&lt;br /&gt;
longer than 64k, we introduced a backwards-compatible extension: if the length&lt;br /&gt;
is below 65535, it will still be transmitted as a two-byte integer in little&lt;br /&gt;
endian format. Otherwise, the two bytes will contain the value 65535, and be&lt;br /&gt;
followed by a decimal ASCII representation of the length, terminated with a zero&lt;br /&gt;
byte. For other one- and two-byte length fields occurring in the protocol, the&lt;br /&gt;
same scheme applies, generalized to be a &amp;quot;length field (original number of bytes)&amp;quot;. (See Figure below)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Image:BCI2000_Messages_LengthField.png|center|thumb|300px|Detailed layout of a length field (m) for a length &amp;lt;math&amp;gt;n \geq 2^{m}-1&amp;lt;/math&amp;gt;]]&lt;br /&gt;
&lt;br /&gt;
{| border=&amp;quot;1&amp;quot; cellpadding=&amp;quot;2&amp;quot;&lt;br /&gt;
|+&lt;br /&gt;
&lt;br /&gt;
===Overview of content descriptors===&lt;br /&gt;
!descriptor  !! description  &lt;br /&gt;
|-&lt;br /&gt;
| 1 || status information string &lt;br /&gt;
|-&lt;br /&gt;
| 2 || system parameter &lt;br /&gt;
|-&lt;br /&gt;
| 3 || system state &lt;br /&gt;
|-&lt;br /&gt;
| 4 || visualization data or brain signal&lt;br /&gt;
|-&lt;br /&gt;
| 5 || state vector &lt;br /&gt;
|-&lt;br /&gt;
| 6 || system command &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Descriptor=1: Status Information Format===&lt;br /&gt;
This section describes the format of the message when the core message is&lt;br /&gt;
a status information string (i.e., the message&#039;s descriptor is 1). In this&lt;br /&gt;
case, the aforementioned content data is a line of ASCII characters in the following format:&lt;br /&gt;
 xxx: status-line-text&lt;br /&gt;
xxx is a three digit number that describes the content of the status&lt;br /&gt;
information string.&lt;br /&gt;
A first digit of `1&#039; indicates status information, a first digit of `2&#039; indicates successful&lt;br /&gt;
operation, a first digit of `3&#039; indicates recoverable errors and a first digit of `4&#039; indicates fatal errors. The two remaining digits define the exact nature of the message, followed by a plain description.&lt;br /&gt;
This procedure is used to communicate errors and to convey status&lt;br /&gt;
information (e.g.,&lt;br /&gt;
the operator module may display the remaining disc space on the machine of the Source module.)&lt;br /&gt;
&lt;br /&gt;
===Descriptor=2: Parameter Format===&lt;br /&gt;
For parameter messages, content data is a line of ASCII characters &lt;br /&gt;
representing a [[parameter definition]] line.&lt;br /&gt;
&lt;br /&gt;
===Descriptor=3: State Format===&lt;br /&gt;
State messages contain a line of ASCII characters representing a &lt;br /&gt;
[[state definition]] line.&lt;br /&gt;
&lt;br /&gt;
===Descriptor=4: Visualization and Brain Signal Data Format===&lt;br /&gt;
This section describes the format of the message when the core message&lt;br /&gt;
is a visualization data/brain signal message (i.e., the descriptor on the message is 4). In this&lt;br /&gt;
case, the content descriptor describes the requested visualization type. &lt;br /&gt;
The currently defined types are 1 (a graph of &#039;&#039;n&#039;&#039;  channels and &#039;&#039;m&#039;&#039;  samples), 2 (a text memo), and 255 (visualization configuration).&lt;br /&gt;
For brain signals, the content descriptor is 1. (See Figure below) &lt;br /&gt;
&lt;br /&gt;
[[Image:BCI2000_Messages_VisualizationData.png|center|thumb|500px|One message in the protocol of type &amp;quot;visualization data&amp;quot;.]]&lt;br /&gt;
&lt;br /&gt;
 &lt;br /&gt;
The following figure illustrates the protocol when the visualization type is 1. The source identifier defines a unique number identifying the process/filter that generated the data. The data type&lt;br /&gt;
can be   &lt;br /&gt;
*0 &amp;lt;tt&amp;gt;(SignalType::int16)&amp;lt;/tt&amp;gt; for integers in little endian format. &lt;br /&gt;
*1 &amp;lt;tt&amp;gt;(SignalType::float24)&amp;lt;/tt&amp;gt; for 3-byte floating-point values: The first two bytes (i.e., A) define the mantissa (signed two-byte integers in little endian format) and the third byte (i.e., B) defines the exponent (signed one-byte integer). The actual floating point value is then calculated as follows: &amp;lt;math&amp;gt;value=A*10^{B}&amp;lt;/math&amp;gt;. &lt;br /&gt;
*2 &amp;lt;tt&amp;gt;(SignalType::float32)&amp;lt;/tt&amp;gt; for 4-byte floating-point values in IEEE 754 format transmitted in little endian byte order. &lt;br /&gt;
*3 &amp;lt;tt&amp;gt;(SignalType::int32)&amp;lt;/tt&amp;gt; for 4-byte signed integer values transmitted in little endian byte order. &lt;br /&gt;
&lt;br /&gt;
The number of channels and samples are self explanatory.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Image:BCI2000_Messages_vistype1(graph).png|center|thumb|600px|One message if the visualization type is 1 (i.e., a graph).]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The following figure illustrates how the data is transferred.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Image:BCI2000_Messages_TransmittedVisualizationDataFormat.png|center|thumb|500px|Graphical representation of the transmitted visualization data format.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The following figure illustrates the protocol when the visualization type is 2. The source identifier is a number uniquely identifying the process/filter that generated the data. (0 for brain signals.)&lt;br /&gt;
The following ASCII text is zero delimited.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Image:BCI2000_Messages_vistype2(memo).png|center|thumb|400px|One message if the visualization type is 2 (i.e., a text memo).]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The following figure illustrates the protocol when the visualization type is 255. The source identifier is a number identifying the process/filter that generated the data. The different configuration IDs are defined in the CFGID enumeration in the  [http://www.bci2000.org/tracproj/browser/trunk/src/shared/defines.h shared/defines.h]&lt;br /&gt;
header file.&lt;br /&gt;
&lt;br /&gt;
The ASCII string then contains the configuration option, as defined by the configuration ID. For example, it might contain &amp;quot;128&amp;quot; if the configuration ID is 4. This will configure the graph to contain exactly 128 samples. When the configuration ID is 5 or 6 (axis labels), the ASCII string consists of a sample number (three digits), a space, and the axis label. Thus, one message&lt;br /&gt;
configures exactly one axis label. As an example, for an X-axis label, the string &amp;quot;003 4.75 Hz&amp;quot; would result in a graph, in which the third sample is labeled &amp;quot;4.75 Hz.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Image:BCI2000_Messages_vistype255(visconfig).png|center|thumb|500px|One message if the visualizationtype is 255 (i.e., visualization configuration).]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====Brain Signal Format====&lt;br /&gt;
The brain signal is transmitted similarly to visualization data (i.e., as described in the Visualization and Brain Signal Data Format above). The visualization type is set to 1 (i.e., graph), source identifier is set to 0. Data type, channels and samples reflect the actual format of data transmitted.&lt;br /&gt;
&lt;br /&gt;
====Control Signal Format====&lt;br /&gt;
Control signals are transmitted identically to the Brain Signal.&lt;br /&gt;
&lt;br /&gt;
===Descriptor=5: State Vector===&lt;br /&gt;
The state vector is defined by a series of &#039;&#039;StateVectorLength&#039;&#039; &lt;br /&gt;
subsequent bytes.&lt;br /&gt;
The value of a given state within the state vector is determined by&lt;br /&gt;
its byte/bit&lt;br /&gt;
location and length definition. The bits in the state vector are&lt;br /&gt;
always sorted&lt;br /&gt;
in ascending order, e.g., for a state with a length of 7 bits,&lt;br /&gt;
starting at byte&lt;br /&gt;
location 2, bit location 3, bit zero is first (byte 2, bit 3), and the&lt;br /&gt;
highest&lt;br /&gt;
bit (bit 7) is last (byte 3, bit 1).&lt;br /&gt;
&lt;br /&gt;
===Descriptor=6: System Command===&lt;br /&gt;
The system command consists of an ASCII string that may end with a&lt;br /&gt;
zero byte (i.e., ASCII code 0).&lt;br /&gt;
The nature of these system commands is defined by the specific&lt;br /&gt;
implementation of&lt;br /&gt;
the modules.&lt;/div&gt;</summary>
		<author><name>Atennissen</name></author>
	</entry>
	<entry>
		<id>https://www.bci2000.org/mediawiki/index.php?title=Technical_Reference:BCI2000_Messages&amp;diff=1733</id>
		<title>Technical Reference:BCI2000 Messages</title>
		<link rel="alternate" type="text/html" href="https://www.bci2000.org/mediawiki/index.php?title=Technical_Reference:BCI2000_Messages&amp;diff=1733"/>
		<updated>2007-04-25T15:48:40Z</updated>

		<summary type="html">&lt;p&gt;Atennissen: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Information transferred between BCI2000 modules is packed into messages.&lt;br /&gt;
Each message content corresponds to a BCI2000 data type such as Parameter, State, or Signal, and is wrapped into a layer that allows for routing the message to an appropriate handler.&lt;br /&gt;
BCI2000 data types know how to write themselves to, and read themselves from, a data stream.&lt;br /&gt;
For example, when the wrapper indicates that a message contains a brain signal, the framework code will route the message to a &amp;quot;brain signal&amp;quot; handler function that, in turn, asks a brain signal object to read itself from the message.&lt;br /&gt;
As another example, when the operator module receives a visualization message, the message wrapper layer will not only be used to direct the message to a visualization handler but also to the visualization window to which the message is addressed.&lt;br /&gt;
&lt;br /&gt;
===Protocol Definition===&lt;br /&gt;
Each message starts&lt;br /&gt;
with a one-byte content descriptor and a one-byte descriptor supplement, followed&lt;br /&gt;
by a number that describes the length of the content. (See Figure 1.1)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Image:BCI2000_Messages_MessageProtocol.png|center|thumb|400px|Fig. 1.1 Layout of one message in the protocol.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The element denoted by &amp;quot;length field(2)&amp;quot; was originally a two-byte integer&lt;br /&gt;
field for the content length in little endian format. To allow for messages&lt;br /&gt;
longer than 64k, we introduced a backwards-compatible extension: if the length&lt;br /&gt;
is below 65535, it will still be transmitted as a two-byte integer in little&lt;br /&gt;
endian format. Otherwise, the two bytes will contain the value 65535, and be&lt;br /&gt;
followed by a decimal ASCII representation of the length, terminated with a zero&lt;br /&gt;
byte. For other one- and two-byte length fields occurring in the protocol, the&lt;br /&gt;
same scheme applies, generalized to be a &amp;quot;length field (original number of bytes)&amp;quot;. (See Figure 1.2)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Image:BCI2000_Messages_LengthField.png|center|thumb|300px|Fig 1.2. Detailed layout of a length field (m) for a length &amp;lt;math&amp;gt;n \geq 2^{m}-1&amp;lt;/math&amp;gt;]]&lt;br /&gt;
&lt;br /&gt;
{| border=&amp;quot;1&amp;quot; cellpadding=&amp;quot;2&amp;quot;&lt;br /&gt;
|+&lt;br /&gt;
&lt;br /&gt;
===Overview of content descriptors===&lt;br /&gt;
!descriptor  !! description  &lt;br /&gt;
|-&lt;br /&gt;
| 1 || status information string &lt;br /&gt;
|-&lt;br /&gt;
| 2 || system parameter &lt;br /&gt;
|-&lt;br /&gt;
| 3 || system state &lt;br /&gt;
|-&lt;br /&gt;
| 4 || visualization data or brain signal&lt;br /&gt;
|-&lt;br /&gt;
| 5 || state vector &lt;br /&gt;
|-&lt;br /&gt;
| 6 || system command &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Descriptor=1: Status Information Format===&lt;br /&gt;
This section describes the format of the message when the core message is&lt;br /&gt;
a status information string (i.e., the message&#039;s descriptor is 1). In this&lt;br /&gt;
case, the aforementioned content data is a line of ASCII characters in the following format:&lt;br /&gt;
 xxx: status-line-text&lt;br /&gt;
xxx is a three digit number that describes the content of the status&lt;br /&gt;
information string.&lt;br /&gt;
A first digit of `1&#039; indicates status information, a first digit of `2&#039; indicates successful&lt;br /&gt;
operation, a first digit of `3&#039; indicates recoverable errors and a first digit of `4&#039; indicates fatal errors. The two remaining digits define the exact nature of the message, followed by a plain description.&lt;br /&gt;
This procedure is used to communicate errors and to convey status&lt;br /&gt;
information (e.g.,&lt;br /&gt;
the operator module may display the remaining disc space on the machine of the Source module.)&lt;br /&gt;
&lt;br /&gt;
===Descriptor=2: Parameter Format===&lt;br /&gt;
For parameter messages, content data is a line of ASCII characters &lt;br /&gt;
representing a [[parameter definition]] line.&lt;br /&gt;
&lt;br /&gt;
===Descriptor=3: State Format===&lt;br /&gt;
State messages contain a line of ASCII characters representing a &lt;br /&gt;
[[state definition]] line.&lt;br /&gt;
&lt;br /&gt;
===Descriptor=4: Visualization and Brain Signal Data Format===&lt;br /&gt;
This section describes the format of the message when the core message&lt;br /&gt;
is a visualization data/brain signal message (i.e., the descriptor on the message is 4). In this&lt;br /&gt;
case, the content descriptor describes the requested visualization type. &lt;br /&gt;
The currently defined types are 1 (a graph of &#039;&#039;n&#039;&#039;  channels and &#039;&#039;m&#039;&#039;  samples), 2 (a text memo), and 255 (visualization configuration).&lt;br /&gt;
For brain signals, the content descriptor is 1. (See Figure 6.1) &lt;br /&gt;
&lt;br /&gt;
[[Image:BCI2000_Messages_VisualizationData.png|center|thumb|500px|Fig. 6.1 One message in the protocol of type &amp;quot;visualization data&amp;quot;.]]&lt;br /&gt;
&lt;br /&gt;
 &lt;br /&gt;
Figure 6.2 illustrates the protocol when the visualization type is 1. The source identifier defines a unique number identifying the process/filter that generated the data. The data type&lt;br /&gt;
can be   &lt;br /&gt;
*0 &amp;lt;tt&amp;gt;(SignalType::int16)&amp;lt;/tt&amp;gt; for integers in little endian format. &lt;br /&gt;
*1 &amp;lt;tt&amp;gt;(SignalType::float24)&amp;lt;/tt&amp;gt; for 3-byte floating-point values: The first two bytes (i.e., A) define the mantissa (signed two-byte integers in little endian format) and the third byte (i.e., B) defines the exponent (signed one-byte integer). The actual floating point value is then calculated as follows: &amp;lt;math&amp;gt;value=A*10^{B}&amp;lt;/math&amp;gt;. &lt;br /&gt;
*2 &amp;lt;tt&amp;gt;(SignalType::float32)&amp;lt;/tt&amp;gt; for 4-byte floating-point values in IEEE 754 format transmitted in little endian byte order. &lt;br /&gt;
*3 &amp;lt;tt&amp;gt;(SignalType::int32)&amp;lt;/tt&amp;gt; for 4-byte signed integer values transmitted in little endian byte order. &lt;br /&gt;
&lt;br /&gt;
The number of channels and samples are self explanatory.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Image:BCI2000_Messages_vistype1(graph).png|center|thumb|600px|Fig. 6.2 One message if the visualization type is 1 (i.e., a graph).]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Figure 6.3 illustrates how the data is transferred.&lt;br /&gt;
&lt;br /&gt;
[[Image:BCI2000_Messages_TransmittedVisualizationDataFormat.png|center|thumb|500px|Graphical representation of the transmitted visualization data format.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Figure 6.4 illustrates the protocol when the visualization type is 2. The source identifier is a number uniquely identifying the process/filter that generated the data. (0 for brain signals.)&lt;br /&gt;
The following ASCII text is zero delimited.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Image:BCI2000_Messages_vistype2(memo).png|center|thumb|400px|Fig. 6.4 One message if the visualization type is 2 (i.e., a text memo).]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Figure 6.5 illustrates the protocol when the visualization type is 255. The source identifier is a number identifying the process/filter that generated the data. The different configuration IDs are defined in the CFGID enumeration in the  [http://www.bci2000.org/tracproj/browser/trunk/src/shared/defines.h shared/defines.h]&lt;br /&gt;
header file.&lt;br /&gt;
&lt;br /&gt;
The ASCII string then contains the configuration option, as defined by the configuration ID. For example, it might contain &amp;quot;128&amp;quot; if the configuration ID is 4. This will configure the graph to contain exactly 128 samples. When the configuration ID is 5 or 6 (axis labels), the ASCII string consists of a sample number (three digits), a space, and the axis label. Thus, one message&lt;br /&gt;
configures exactly one axis label. As an example, for an X-axis label, the string &amp;quot;003 4.75 Hz&amp;quot; would result in a graph, in which the third sample is labeled &amp;quot;4.75 Hz.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Image:BCI2000_Messages_vistype255(visconfig).png|center|thumb|500px|Fig. 6.5 One message if the visualizationtype is 255 (i.e., visualization configuration).]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====Brain Signal Format====&lt;br /&gt;
The brain signal is transmitted similarly to visualization data (i.e., as described in Section 6). The visualization type is set to 1 (i.e., graph), source identifier is set to 0. Data type, channels and samples reflect the actual format of data transmitted.&lt;br /&gt;
&lt;br /&gt;
====Control Signal Format====&lt;br /&gt;
Control signals are transmitted identically to the Brain Signal.&lt;br /&gt;
&lt;br /&gt;
===Descriptor=5: State Vector===&lt;br /&gt;
The state vector is defined by a series of &#039;&#039;StateVectorLength&#039;&#039; &lt;br /&gt;
subsequent bytes.&lt;br /&gt;
The value of a given state within the state vector is determined by&lt;br /&gt;
its byte/bit&lt;br /&gt;
location and length definition. The bits in the state vector are&lt;br /&gt;
always sorted&lt;br /&gt;
in ascending order, e.g., for a state with a length of 7 bits,&lt;br /&gt;
starting at byte&lt;br /&gt;
location 2, bit location 3, bit zero is first (byte 2, bit 3), and the&lt;br /&gt;
highest&lt;br /&gt;
bit (bit 7) is last (byte 3, bit 1).&lt;br /&gt;
&lt;br /&gt;
===Descriptor=6: System Command===&lt;br /&gt;
The system command consists of an ASCII string that may end with a&lt;br /&gt;
zero byte (i.e., ASCII code 0).&lt;br /&gt;
The nature of these system commands is defined by the specific&lt;br /&gt;
implementation of&lt;br /&gt;
the modules.&lt;/div&gt;</summary>
		<author><name>Atennissen</name></author>
	</entry>
	<entry>
		<id>https://www.bci2000.org/mediawiki/index.php?title=Technical_Reference:State_Definition&amp;diff=1731</id>
		<title>Technical Reference:State Definition</title>
		<link rel="alternate" type="text/html" href="https://www.bci2000.org/mediawiki/index.php?title=Technical_Reference:State_Definition&amp;diff=1731"/>
		<updated>2007-04-25T14:41:36Z</updated>

		<summary type="html">&lt;p&gt;Atennissen: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page describes the concept of BCI2000 states, in conjunction with their textual representation as a &amp;quot;state line&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
For information about how to access state values from code, please refer to [[Programming Reference:States]].&lt;br /&gt;
For information about individual parameters, please refer to [[User Reference:States]].&lt;br /&gt;
&lt;br /&gt;
==State Concept==&lt;br /&gt;
States are variables that represent the internal state of a BCI2000 system, as it is evolving over time in response to:&lt;br /&gt;
*brain signal input&lt;br /&gt;
*user interaction through the operator interface&lt;br /&gt;
*trial sequencing by the application module.&lt;br /&gt;
&lt;br /&gt;
Typical entities encoded by states are:&lt;br /&gt;
*whether the system is running or suspended&lt;br /&gt;
*the time when a block of data was recorded &lt;br /&gt;
*stimulus or task being presented&lt;br /&gt;
*the classification result&lt;br /&gt;
*the state of an external marker (trigger) to be saved for off-line analysis.&lt;br /&gt;
&lt;br /&gt;
Typically, state values change once per block of data, or once per trial.&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
==State Vector==&lt;br /&gt;
In a BCI2000 system, a collection of states is maintained as a &#039;&#039;State List&#039;&#039;.&lt;br /&gt;
For each state present in that state list, its value is kept as a range of bits in a bit vector called &#039;&#039;State Vector&#039;&#039;.&lt;br /&gt;
BCI2000 modules and filters may read and write state values during processing.&lt;br /&gt;
The state vector&#039;s content is saved, in its binary form, into [[BCI2000 data files]] per-block.&lt;br /&gt;
Using the ByteLocation, BitLocation, and Length fields from the state definitions present in a file, a state&#039;s value may be read from the data file.&lt;br /&gt;
&lt;br /&gt;
A state vector is a narrowly packed bit field in &#039;&#039;&#039;big endian&#039;&#039;&#039; ordering.&lt;br /&gt;
This implies that, for a state containing more than a single bit, &#039;&#039;&#039;less&#039;&#039;&#039; significant bits are placed at &#039;&#039;&#039;higher&#039;&#039;&#039; bit and byte locations.&lt;br /&gt;
&lt;br /&gt;
As an example, consider a state vector consisting of a 1-bit state &amp;quot;Running&amp;quot;, and a 16-bit state &amp;quot;SourceTime&amp;quot;. This will result in a three-byte state vector layout like this:&lt;br /&gt;
{|border=&amp;quot;1&amp;quot; cellspacing=&amp;quot;0&amp;quot; cellpadding=&amp;quot;1&amp;quot;&lt;br /&gt;
!colspan=&amp;quot;8&amp;quot;|State Vector Byte 1 &lt;br /&gt;
!colspan=&amp;quot;8&amp;quot;|State Vector Byte 2 &lt;br /&gt;
!colspan=&amp;quot;8&amp;quot;|State Vector Byte 3&lt;br /&gt;
|-&lt;br /&gt;
!7!!6!!5!!4!!3!!2!!1!!0&lt;br /&gt;
!7!!6!!5!!4!!3!!2!!1!!0&lt;br /&gt;
!7!!6!!5!!4!!3!!2!!1!!0&lt;br /&gt;
|-&lt;br /&gt;
!Running!!colspan=&amp;quot;16&amp;quot;|SourceTime!!colspan=&amp;quot;7&amp;quot;|unused&lt;br /&gt;
|-&lt;br /&gt;
!0&lt;br /&gt;
!15!!14!!13!!12!!11!!10!!9!!8!!7!!6!!5!!4!!3!!2!!1!!0&lt;br /&gt;
!colspan=&amp;quot;7&amp;quot;|&amp;amp;nbsp;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==State Lines==&lt;br /&gt;
State lines are a human-readable format used to represent individual states in&lt;br /&gt;
*[[BCI2000 data files]],&lt;br /&gt;
*[[BCI2000 messages]] sent between modules.&lt;br /&gt;
Core modules and operator module use this format to communicate in the system initialization phase, as well as during system performance and for system termination.&lt;br /&gt;
&lt;br /&gt;
The format of a state line is&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Name Length Value ByteLocation BitLocation CRLF&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
where &amp;lt;tt&amp;gt;Length&amp;lt;/tt&amp;gt; refers to the number of bits used to represent the state&#039;s value,&lt;br /&gt;
and &amp;lt;tt&amp;gt;ByteLocation&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;BitLocation&amp;lt;/tt&amp;gt; refer to its position in a [[State Vector]], with &amp;lt;tt&amp;gt;BitLocation&amp;lt;/tt&amp;gt; ranging from 0..7.&lt;br /&gt;
&lt;br /&gt;
Depending on the context of a state line, one or more of its fields may be ignored:&lt;br /&gt;
*In a State message sent from the operator module to a core module, Length, ByteLocation, and BitLocation will be ignored.&lt;br /&gt;
*In a State line contained in a data file, the Value field matches the state&#039;s value stored with the first block of data samples.&lt;br /&gt;
&lt;br /&gt;
Generally, the Value field specifies an &#039;&#039;initial value&#039;&#039; of a state. Actual values are stored in the [[State Vector]] data structure.&lt;br /&gt;
-----&lt;br /&gt;
See also: [[User Reference:States]]&lt;/div&gt;</summary>
		<author><name>Atennissen</name></author>
	</entry>
</feed>