<?xml version="1.0"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/">
	<channel>
		<title>BCI2000 Wiki  - Recent changes [en]</title>
		<link>https://www.bci2000.org/mediawiki/index.php/Special:RecentChanges</link>
		<description>Track the most recent changes to the wiki in this feed.</description>
		<language>en</language>
		<generator>MediaWiki 1.43.8</generator>
		<lastBuildDate>Thu, 01 Oct 2026 19:52:59 GMT</lastBuildDate>
		<item>
			<title>BCI2000 to BIDS Converter</title>
			<link>https://www.bci2000.org/mediawiki/index.php?title=BCI2000_to_BIDS_Converter&amp;diff=12608&amp;oldid=12607</link>
			<guid isPermaLink="false">https://www.bci2000.org/mediawiki/index.php?title=BCI2000_to_BIDS_Converter&amp;diff=12608&amp;oldid=12607</guid>
			<description>&lt;p&gt;&lt;/p&gt;
&lt;table style=&quot;background-color: #fff; color: #202122;&quot; data-mw=&quot;interface&quot;&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;tr class=&quot;diff-title&quot; lang=&quot;en&quot;&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;← Older revision&lt;/td&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;Revision as of 00:03, 29 September 2026&lt;/td&gt;
				&lt;/tr&gt;&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot; id=&quot;mw-diff-left-l37&quot;&gt;Line 37:&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 37:&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&amp;lt;/pre&amp;gt;&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&amp;lt;/pre&amp;gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;−&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;&amp;lt;!-- Add the public source-&lt;/del&gt;code &lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;repository URL here when the repository is published&lt;/del&gt;. --&lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;&amp;gt;&lt;/del&gt;&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;Source &lt;/ins&gt;code&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;:&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt; &lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;[https://github&lt;/ins&gt;.&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;com/alexanderspeer/BCI2000-to&lt;/ins&gt;-&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;BIDS&lt;/ins&gt;-&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;Converter BCI2000 to BIDS Converter on GitHub]&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;The converter relies on BCI2000Tools for reading BCI2000 recordings. See [[BCI2000Tools.EventRelated|BCI2000Tools]] for information about BCI2000&amp;#039;s Python tools.&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;The converter relies on BCI2000Tools for reading BCI2000 recordings. See [[BCI2000Tools.EventRelated|BCI2000Tools]] for information about BCI2000&amp;#039;s Python tools.&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot; id=&quot;mw-diff-left-l1230&quot;&gt;Line 1,230:&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 1,232:&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;# [https://bids-specification.readthedocs.io/en/stable/ BIDS Specification].&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;# [https://bids-specification.readthedocs.io/en/stable/ BIDS Specification].&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;# [https://bids-standard.github.io/bids-validator/ BIDS Validator].&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;# [https://bids-standard.github.io/bids-validator/ BIDS Validator].&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;# frederik-lam. [https://github.com/Cybernetics-and-Motor-Physiology-Lab/BCI2000-BIDS_converter BCI2000-BIDS_converter]. Cybernetics-and-Motor-Physiology-Lab. MATLAB-based framework for converting BCI2000 &amp;lt;code&amp;gt;.dat&amp;lt;/code&amp;gt; recordings into BIDS-compatible electrophysiology datasets.&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;==See also==&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;==See also==&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;

&lt;!-- diff cache key wikidb-bci_:diff:1.41:old-12607:rev-12608:php=table --&gt;
&lt;/table&gt;</description>
			<pubDate>Tue, 29 Sep 2026 00:03:34 GMT</pubDate>
			<dc:creator>Aes2376</dc:creator>
			<comments>https://www.bci2000.org/mediawiki/index.php/Talk:BCI2000_to_BIDS_Converter</comments>
		</item>
		<item>
			<title>BCI2000 to BIDS Converter</title>
			<link>https://www.bci2000.org/mediawiki/index.php?title=BCI2000_to_BIDS_Converter&amp;diff=12607&amp;oldid=0</link>
			<guid isPermaLink="false">https://www.bci2000.org/mediawiki/index.php?title=BCI2000_to_BIDS_Converter&amp;diff=12607&amp;oldid=0</guid>
			<description>&lt;p&gt;Created page with &amp;quot;==Synopsis==  &amp;#039;&amp;#039;&amp;#039;BCI2000 to BIDS Converter&amp;#039;&amp;#039;&amp;#039; (&amp;lt;code&amp;gt;bci2000-bids&amp;lt;/code&amp;gt;) is an open-source Python tool for converting BCI2000 &amp;lt;code&amp;gt;.dat&amp;lt;/code&amp;gt; recordings into datasets organized according to the [https://bids.neuroimaging.io/ Brain Imaging Data Structure (BIDS)].  The converter reads signals, parameters, state definitions, and state values stored in a BCI2000 data file and maps them into BIDS-compatible electrophysiology, event, motion, and metadata files.  The convert...&amp;quot;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;New page&lt;/b&gt;&lt;/p&gt;&lt;div&gt;==Synopsis==&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;BCI2000 to BIDS Converter&amp;#039;&amp;#039;&amp;#039; (&amp;lt;code&amp;gt;bci2000-bids&amp;lt;/code&amp;gt;) is an open-source Python tool for converting BCI2000 &amp;lt;code&amp;gt;.dat&amp;lt;/code&amp;gt; recordings into datasets organized according to the [https://bids.neuroimaging.io/ Brain Imaging Data Structure (BIDS)].&lt;br /&gt;
&lt;br /&gt;
The converter reads signals, parameters, state definitions, and state values stored in a BCI2000 data file and maps them into BIDS-compatible electrophysiology, event, motion, and metadata files.&lt;br /&gt;
&lt;br /&gt;
The converter supports:&lt;br /&gt;
&lt;br /&gt;
* Behavioral/state-only BIDS datasets.&lt;br /&gt;
* EEG datasets.&lt;br /&gt;
* Intracranial EEG (iEEG) datasets, including ECoG, SEEG, and DBS recordings.&lt;br /&gt;
* Conversion of BCI2000 signal channels to EDF.&lt;br /&gt;
* Conversion of BCI2000 state transitions into &amp;lt;code&amp;gt;*_events.tsv&amp;lt;/code&amp;gt;.&lt;br /&gt;
* Conversion of continuous BCI2000 states into BIDS motion files.&lt;br /&gt;
* Reusable JSON or YAML state-routing profiles.&lt;br /&gt;
* Automatic generation of review-required starter profiles.&lt;br /&gt;
* Conversion of multiple &amp;lt;code&amp;gt;.dat&amp;lt;/code&amp;gt; files into sequential BIDS runs.&lt;br /&gt;
* Optional preservation of the original BCI2000 files in &amp;lt;code&amp;gt;sourcedata/&amp;lt;/code&amp;gt;.&lt;br /&gt;
* SHA-256 checksums for preserved source recordings.&lt;br /&gt;
* Command-line and graphical interfaces.&lt;br /&gt;
* Optional validation using the [https://bids-standard.github.io/bids-validator/ BIDS Validator].&lt;br /&gt;
&lt;br /&gt;
The converter is intended for offline organization and export of data that have already been recorded by BCI2000. It does not modify the original &amp;lt;code&amp;gt;.dat&amp;lt;/code&amp;gt; recordings.&lt;br /&gt;
&lt;br /&gt;
==Project Source==&lt;br /&gt;
&lt;br /&gt;
The Python package and command-line program are named:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
bci2000-bids&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The Python import package is:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
bci2000_bids&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!-- Add the public source-code repository URL here when the repository is published. --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The converter relies on BCI2000Tools for reading BCI2000 recordings. See [[BCI2000Tools.EventRelated|BCI2000Tools]] for information about BCI2000&amp;#039;s Python tools.&lt;br /&gt;
&lt;br /&gt;
==Versioning==&lt;br /&gt;
&lt;br /&gt;
===Author===&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Alexander Speer&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
Friedman Lab, Department of Neurosurgery&lt;br /&gt;
&lt;br /&gt;
Washington University in St. Louis&lt;br /&gt;
&lt;br /&gt;
Developed in the Friedman Lab.&lt;br /&gt;
&lt;br /&gt;
Contact: speer@wustl.edu&lt;br /&gt;
&lt;br /&gt;
===Version History===&lt;br /&gt;
&lt;br /&gt;
Current software version: &amp;#039;&amp;#039;&amp;#039;0.1.0&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
The initial implementation provides:&lt;br /&gt;
&lt;br /&gt;
* Reading of BCI2000 &amp;lt;code&amp;gt;.dat&amp;lt;/code&amp;gt; recordings using BCI2000Tools.&lt;br /&gt;
* Single-file and multi-file conversion.&lt;br /&gt;
* Deterministic BIDS run numbering.&lt;br /&gt;
* Behavioral, EEG, and iEEG output.&lt;br /&gt;
* EDF electrophysiology output.&lt;br /&gt;
* BIDS event generation from BCI2000 states.&lt;br /&gt;
* BIDS motion output from continuous BCI2000 states.&lt;br /&gt;
* JSON and YAML state-routing profiles.&lt;br /&gt;
* Automatic starter-profile generation.&lt;br /&gt;
* Source-file preservation and SHA-256 checksums.&lt;br /&gt;
* Staged conversion and protected publication of output datasets.&lt;br /&gt;
* Command-line interface.&lt;br /&gt;
* Tkinter graphical interface.&lt;br /&gt;
* Optional BIDS validation.&lt;br /&gt;
&lt;br /&gt;
The software requires Python 3.10 or newer.&lt;br /&gt;
&lt;br /&gt;
==Functional Description==&lt;br /&gt;
&lt;br /&gt;
===BCI2000 Data Model===&lt;br /&gt;
&lt;br /&gt;
A standard BCI2000 &amp;lt;code&amp;gt;.dat&amp;lt;/code&amp;gt; file contains the recorded signal together with BCI2000 parameters and states. See [[Technical Reference:BCI2000 File Format|BCI2000 File Format]] for the complete native format specification.&lt;br /&gt;
&lt;br /&gt;
The converter uses these components differently:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! BCI2000 information&lt;br /&gt;
! Use by the converter&lt;br /&gt;
|-&lt;br /&gt;
| Signal channels&lt;br /&gt;
| May be exported as BIDS EEG or iEEG electrophysiology data.&lt;br /&gt;
|-&lt;br /&gt;
| Sampling rate&lt;br /&gt;
| Used as the sampling frequency of the exported recording and motion data.&lt;br /&gt;
|-&lt;br /&gt;
| Channel names&lt;br /&gt;
| Used to name channels in the electrophysiology output.&lt;br /&gt;
|-&lt;br /&gt;
| Channel units&lt;br /&gt;
| Used when constructing the BIDS channel table and EDF output.&lt;br /&gt;
|-&lt;br /&gt;
| State definitions&lt;br /&gt;
| Used to identify states that may be mapped to events, event metadata, or continuous motion channels.&lt;br /&gt;
|-&lt;br /&gt;
| State samples&lt;br /&gt;
| Used to generate event timing and continuous motion data.&lt;br /&gt;
|-&lt;br /&gt;
| Parameters&lt;br /&gt;
| Used to obtain selected recording metadata such as sampling rate, channel names, channel units, application, signal source, and data format.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Not every BCI2000 state or parameter is automatically exported. State routing is controlled by a conversion profile so that the scientific meaning of study-specific states remains under user control.&lt;br /&gt;
&lt;br /&gt;
===Conversion Pipeline===&lt;br /&gt;
&lt;br /&gt;
The overall conversion process is:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
BCI2000 .dat recording(s)&lt;br /&gt;
          |&lt;br /&gt;
          v&lt;br /&gt;
   BCI2000Tools reader&lt;br /&gt;
          |&lt;br /&gt;
          +---- signal channels&lt;br /&gt;
          |&lt;br /&gt;
          +---- parameters&lt;br /&gt;
          |&lt;br /&gt;
          +---- state definitions and values&lt;br /&gt;
          |&lt;br /&gt;
          v&lt;br /&gt;
 State-routing profile&lt;br /&gt;
          |&lt;br /&gt;
          +---- event states --------&amp;gt; *_events.tsv&lt;br /&gt;
          |&lt;br /&gt;
          +---- event metadata ------&amp;gt; additional event columns&lt;br /&gt;
          |&lt;br /&gt;
          +---- continuous states ---&amp;gt; motion/*.tsv&lt;br /&gt;
          |&lt;br /&gt;
          +---- ignored states&lt;br /&gt;
          |&lt;br /&gt;
          v&lt;br /&gt;
     BIDS writers&lt;br /&gt;
          |&lt;br /&gt;
          +---- EEG/iEEG EDF&lt;br /&gt;
          +---- channels.tsv&lt;br /&gt;
          +---- JSON sidecars&lt;br /&gt;
          +---- events.tsv&lt;br /&gt;
          +---- motion files&lt;br /&gt;
          +---- participants.tsv&lt;br /&gt;
          +---- dataset_description.json&lt;br /&gt;
          |&lt;br /&gt;
          v&lt;br /&gt;
   Optional BIDS validation&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For a normal conversion, the software:&lt;br /&gt;
&lt;br /&gt;
# Loads the optional conversion configuration.&lt;br /&gt;
# Resolves subject, session, task, datatype, neural-export, preservation, and output settings.&lt;br /&gt;
# Normalizes BIDS labels.&lt;br /&gt;
# Discovers input &amp;lt;code&amp;gt;.dat&amp;lt;/code&amp;gt; files.&lt;br /&gt;
# Sorts the files and assigns sequential BIDS run numbers.&lt;br /&gt;
# Loads the requested state-routing profile.&lt;br /&gt;
# If no profile is supplied, analyzes the first recording and generates a review-required starter profile.&lt;br /&gt;
# Creates a temporary staging dataset.&lt;br /&gt;
# Reads each BCI2000 recording.&lt;br /&gt;
# Extracts states referenced by the active profile.&lt;br /&gt;
# Generates BIDS events and/or motion data.&lt;br /&gt;
# Writes electrophysiology data if neural export is enabled.&lt;br /&gt;
# Optionally copies source data and calculates checksums.&lt;br /&gt;
# Optionally validates the staged BIDS dataset.&lt;br /&gt;
# Publishes the completed dataset.&lt;br /&gt;
&lt;br /&gt;
The original &amp;lt;code&amp;gt;.dat&amp;lt;/code&amp;gt; files are read-only during normal conversion.&lt;br /&gt;
&lt;br /&gt;
==Supported Input==&lt;br /&gt;
&lt;br /&gt;
===BCI2000 Files===&lt;br /&gt;
&lt;br /&gt;
The converter accepts:&lt;br /&gt;
&lt;br /&gt;
* A single BCI2000 &amp;lt;code&amp;gt;.dat&amp;lt;/code&amp;gt; file.&lt;br /&gt;
* Multiple &amp;lt;code&amp;gt;.dat&amp;lt;/code&amp;gt; files.&lt;br /&gt;
* A directory containing &amp;lt;code&amp;gt;.dat&amp;lt;/code&amp;gt; files.&lt;br /&gt;
* A directory tree containing &amp;lt;code&amp;gt;.dat&amp;lt;/code&amp;gt; files when recursive discovery is enabled.&lt;br /&gt;
&lt;br /&gt;
For directory input, normal discovery searches the immediate directory.&lt;br /&gt;
&lt;br /&gt;
Recursive discovery may be enabled with:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
--recursive&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Input recordings are sorted deterministically. Each discovered recording becomes a separate BIDS run beginning with &amp;lt;code&amp;gt;run-01&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
recording1.dat  -&amp;gt; run-01&lt;br /&gt;
recording2.dat  -&amp;gt; run-02&lt;br /&gt;
recording3.dat  -&amp;gt; run-03&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The converter does not currently infer recording groups from BCI2000 metadata. The supplied files are treated as recordings belonging to the subject/session/task selected for that conversion.&lt;br /&gt;
&lt;br /&gt;
Duplicate source filenames are rejected even if the files originate from different directories.&lt;br /&gt;
&lt;br /&gt;
===Reading BCI2000 Data===&lt;br /&gt;
&lt;br /&gt;
BCI2000 files are opened using:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
BCI2000Tools.FileReader.bcistream&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The reader obtains:&lt;br /&gt;
&lt;br /&gt;
* Parameters.&lt;br /&gt;
* State definitions.&lt;br /&gt;
* Sampling frequency.&lt;br /&gt;
* Number of samples.&lt;br /&gt;
* Number of channels.&lt;br /&gt;
* Channel names.&lt;br /&gt;
* Channel units.&lt;br /&gt;
&lt;br /&gt;
Signal and state arrays are decoded when required by the requested conversion.&lt;br /&gt;
&lt;br /&gt;
The sampling frequency is first obtained from the BCI2000 &amp;lt;code&amp;gt;SamplingRate&amp;lt;/code&amp;gt; parameter. If that cannot be interpreted, the sampling frequency reported by the BCI2000Tools stream is used.&lt;br /&gt;
&lt;br /&gt;
Channel names are normally obtained from:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
ChannelNames&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If valid channel names are unavailable, fallback names are generated:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
ch001&lt;br /&gt;
ch002&lt;br /&gt;
ch003&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Channel units are read from:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
SourceChUnits&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
When units are unavailable for neural EDF output, the converter currently uses &amp;lt;code&amp;gt;uV&amp;lt;/code&amp;gt; as the fallback unit.&lt;br /&gt;
&lt;br /&gt;
The converter requests calibrated signal values from BCI2000Tools.&lt;br /&gt;
&lt;br /&gt;
===Companion Files===&lt;br /&gt;
&lt;br /&gt;
The current converter operates on information embedded in BCI2000 &amp;lt;code&amp;gt;.dat&amp;lt;/code&amp;gt; files.&lt;br /&gt;
&lt;br /&gt;
It does not automatically ingest companion files such as separate parameter files, video files, imaging files, or other study-specific files.&lt;br /&gt;
&lt;br /&gt;
==BIDS Output==&lt;br /&gt;
&lt;br /&gt;
===Supported BIDS Datatypes===&lt;br /&gt;
&lt;br /&gt;
The converter currently supports:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Datatype&lt;br /&gt;
! Purpose&lt;br /&gt;
! Neural export&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;beh&amp;lt;/code&amp;gt;&lt;br /&gt;
| Behavioral/state-only data&lt;br /&gt;
| No&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;eeg&amp;lt;/code&amp;gt;&lt;br /&gt;
| Scalp EEG recordings&lt;br /&gt;
| Yes&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;ieeg&amp;lt;/code&amp;gt;&lt;br /&gt;
| Intracranial electrophysiology&lt;br /&gt;
| Yes&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
For iEEG conversion, the neural channel type may be specified as:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;ECOG&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;SEEG&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;DBS&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Channels beginning with &amp;lt;code&amp;gt;ECG&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;EKG&amp;lt;/code&amp;gt; are classified as ECG channels.&lt;br /&gt;
&lt;br /&gt;
===Generated Dataset Structure===&lt;br /&gt;
&lt;br /&gt;
A conversion containing iEEG, events, motion data, and preserved source data may produce a structure similar to:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
bids/&lt;br /&gt;
├── dataset_description.json&lt;br /&gt;
├── participants.tsv&lt;br /&gt;
├── participants.json&lt;br /&gt;
├── sub-001/&lt;br /&gt;
│   └── ses-01/&lt;br /&gt;
│       ├── ieeg/&lt;br /&gt;
│       │   ├── sub-001_ses-01_task-motor_run-01_ieeg.edf&lt;br /&gt;
│       │   ├── sub-001_ses-01_task-motor_run-01_ieeg.json&lt;br /&gt;
│       │   ├── sub-001_ses-01_task-motor_run-01_channels.tsv&lt;br /&gt;
│       │   ├── sub-001_ses-01_task-motor_run-01_events.tsv&lt;br /&gt;
│       │   └── sub-001_ses-01_task-motor_run-01_events.json&lt;br /&gt;
│       └── motion/&lt;br /&gt;
│           ├── sub-001_ses-01_task-motor_run-01_tracksys-unknown_motion.tsv&lt;br /&gt;
│           ├── sub-001_ses-01_task-motor_run-01_tracksys-unknown_motion.json&lt;br /&gt;
│           └── sub-001_ses-01_task-motor_run-01_tracksys-unknown_channels.tsv&lt;br /&gt;
├── sourcedata/&lt;br /&gt;
│   └── sub-001/&lt;br /&gt;
│       └── ses-01/&lt;br /&gt;
│           └── bci2000/&lt;br /&gt;
│               ├── recording.dat&lt;br /&gt;
│               └── checksums.tsv&lt;br /&gt;
└── code/&lt;br /&gt;
    └── bci2000-bids/&lt;br /&gt;
        └── auto-profile-motor.json&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;code/bci2000-bids/auto-profile-*.json&amp;lt;/code&amp;gt; file is generated only when automatic profile generation is used.&lt;br /&gt;
&lt;br /&gt;
Behavioral-only conversion does not create a placeholder electrophysiology file.&lt;br /&gt;
&lt;br /&gt;
===Dataset-Level Files===&lt;br /&gt;
&lt;br /&gt;
The converter creates or maintains:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;dataset_description.json&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;participants.tsv&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;participants.json&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The generated dataset description identifies the dataset as raw BIDS data and records &amp;lt;code&amp;gt;bci2000-bids&amp;lt;/code&amp;gt; as conversion software.&lt;br /&gt;
&lt;br /&gt;
The implementation writes BIDS version:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
1.10.1&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The participant table initially contains the BIDS participant identifier.&lt;br /&gt;
&lt;br /&gt;
Study-specific clinical information is not automatically inferred from BCI2000 recordings.&lt;br /&gt;
&lt;br /&gt;
==BCI2000 State Profiles==&lt;br /&gt;
&lt;br /&gt;
===Purpose===&lt;br /&gt;
&lt;br /&gt;
BCI2000 applications may define many study-specific states. Their names alone are not sufficient to determine their scientific meaning.&lt;br /&gt;
&lt;br /&gt;
For this reason, the converter uses a &amp;#039;&amp;#039;&amp;#039;state-routing profile&amp;#039;&amp;#039;&amp;#039; to determine how states should be represented in BIDS.&lt;br /&gt;
&lt;br /&gt;
Profiles may be written in:&lt;br /&gt;
&lt;br /&gt;
* JSON.&lt;br /&gt;
* YAML.&lt;br /&gt;
&lt;br /&gt;
A state may be assigned to:&lt;br /&gt;
&lt;br /&gt;
* An event.&lt;br /&gt;
* An additional event column.&lt;br /&gt;
* A continuous motion channel.&lt;br /&gt;
* The ignore list.&lt;br /&gt;
&lt;br /&gt;
A state should not be assigned to multiple routing categories.&lt;br /&gt;
&lt;br /&gt;
===Example Profile===&lt;br /&gt;
&lt;br /&gt;
A simple profile may look like:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
name: generic-motion&lt;br /&gt;
&lt;br /&gt;
metadata:&lt;br /&gt;
  tracking_system: unknown&lt;br /&gt;
&lt;br /&gt;
events:&lt;br /&gt;
  Marker:&lt;br /&gt;
    strategy: rising_edge&lt;br /&gt;
    trial_type: marker&lt;br /&gt;
&lt;br /&gt;
motion:&lt;br /&gt;
  PositionX:&lt;br /&gt;
    column: position_x&lt;br /&gt;
    type: POSITION&lt;br /&gt;
    units: arbitrary&lt;br /&gt;
&lt;br /&gt;
ignore:&lt;br /&gt;
  - SourceTime&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In this example:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;Marker&amp;lt;/code&amp;gt; creates BIDS event rows.&lt;br /&gt;
* &amp;lt;code&amp;gt;PositionX&amp;lt;/code&amp;gt; becomes a continuous BIDS motion channel.&lt;br /&gt;
* &amp;lt;code&amp;gt;SourceTime&amp;lt;/code&amp;gt; is deliberately ignored.&lt;br /&gt;
&lt;br /&gt;
===Profile Validation===&lt;br /&gt;
&lt;br /&gt;
Profiles are checked before conversion.&lt;br /&gt;
&lt;br /&gt;
Invalid profiles include cases such as:&lt;br /&gt;
&lt;br /&gt;
* Invalid JSON or YAML.&lt;br /&gt;
* Unsupported event strategies.&lt;br /&gt;
* Duplicate state routing.&lt;br /&gt;
* Invalid event-column definitions.&lt;br /&gt;
* Duplicate event-column names.&lt;br /&gt;
* Reserved event-column names.&lt;br /&gt;
* Invalid motion definitions.&lt;br /&gt;
* Invalid metadata structures.&lt;br /&gt;
&lt;br /&gt;
The standard BIDS event fields:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
onset&lt;br /&gt;
duration&lt;br /&gt;
trial_type&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
are reserved and cannot be redefined as custom event columns.&lt;br /&gt;
&lt;br /&gt;
==Automatic Profile Generation==&lt;br /&gt;
&lt;br /&gt;
If a profile is not supplied, the converter may inspect the first recording and create a starter profile.&lt;br /&gt;
&lt;br /&gt;
The automatic profile generator examines properties such as:&lt;br /&gt;
&lt;br /&gt;
* State name.&lt;br /&gt;
* State bit width.&lt;br /&gt;
* Minimum value.&lt;br /&gt;
* Maximum value.&lt;br /&gt;
* Number of unique values.&lt;br /&gt;
* Number of transitions.&lt;br /&gt;
* Transition fraction.&lt;br /&gt;
* Number of nonzero samples.&lt;br /&gt;
* Percentage of nonzero samples.&lt;br /&gt;
&lt;br /&gt;
States with names suggesting continuously varying signals such as joystick, cursor, gaze, position, or similar values may be proposed as motion channels.&lt;br /&gt;
&lt;br /&gt;
Low-cardinality or event-like states may be proposed as events.&lt;br /&gt;
&lt;br /&gt;
Internal-looking states such as:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;SourceTime&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;Running&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;Recording&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
may be proposed for exclusion.&lt;br /&gt;
&lt;br /&gt;
Automatically generated profiles contain:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;quot;review_required&amp;quot;: true&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
and are saved inside the BIDS dataset under:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
code/bci2000-bids/&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Automatically generated profiles are suggestions and should be reviewed before scientific use.&amp;#039;&amp;#039;&amp;#039; The converter cannot determine the experimental meaning of a state from its name or numeric behavior alone.&lt;br /&gt;
&lt;br /&gt;
==Event Conversion==&lt;br /&gt;
&lt;br /&gt;
BCI2000 states may be converted into BIDS &amp;lt;code&amp;gt;*_events.tsv&amp;lt;/code&amp;gt; rows.&lt;br /&gt;
&lt;br /&gt;
The base event table contains:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
onset    duration    trial_type&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Onsets and durations are expressed in seconds.&lt;br /&gt;
&lt;br /&gt;
===Event Strategies===&lt;br /&gt;
&lt;br /&gt;
The following event strategies are supported:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Strategy&lt;br /&gt;
! Behavior&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;rising_edge&amp;lt;/code&amp;gt;&lt;br /&gt;
| Creates an event when the state changes from zero to nonzero.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;falling_edge&amp;lt;/code&amp;gt;&lt;br /&gt;
| Creates an event when the state changes from nonzero to zero.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;change&amp;lt;/code&amp;gt;&lt;br /&gt;
| Creates an event whenever the state value changes.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;value_change&amp;lt;/code&amp;gt;&lt;br /&gt;
| Creates an event whenever the state value changes.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;nonzero_change&amp;lt;/code&amp;gt;&lt;br /&gt;
| Creates an event when a transition results in a nonzero value.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;interval&amp;lt;/code&amp;gt;&lt;br /&gt;
| Treats each continuous nonzero period as an event interval.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Edge and value-change events have zero duration.&lt;br /&gt;
&lt;br /&gt;
For &amp;lt;code&amp;gt;interval&amp;lt;/code&amp;gt;, the duration corresponds to the length of the contiguous nonzero period.&lt;br /&gt;
&lt;br /&gt;
===Additional Event Columns===&lt;br /&gt;
&lt;br /&gt;
Other BCI2000 states may be mapped as additional columns associated with generated events.&lt;br /&gt;
&lt;br /&gt;
For example, a task may use one state to trigger an event while states such as condition, target, block, response type, or trial number are sampled at that event and placed into additional TSV columns.&lt;br /&gt;
&lt;br /&gt;
Additional nonstandard columns are described in the corresponding &amp;lt;code&amp;gt;*_events.json&amp;lt;/code&amp;gt; sidecar.&lt;br /&gt;
&lt;br /&gt;
An additional event-column mapping by itself does not create an event. An event rule must first define when event rows are generated.&lt;br /&gt;
&lt;br /&gt;
==Motion and Continuous State Conversion==&lt;br /&gt;
&lt;br /&gt;
Continuously varying BCI2000 states may be written to the BIDS &amp;lt;code&amp;gt;motion/&amp;lt;/code&amp;gt; directory.&lt;br /&gt;
&lt;br /&gt;
Examples may include states representing:&lt;br /&gt;
&lt;br /&gt;
* Joystick position.&lt;br /&gt;
* Cursor position.&lt;br /&gt;
* Eye position.&lt;br /&gt;
* Gaze position.&lt;br /&gt;
* Limb position.&lt;br /&gt;
* Other continuous task or kinematic variables.&lt;br /&gt;
&lt;br /&gt;
The converter does not determine these meanings automatically during normal conversion. The user specifies them through the state-routing profile.&lt;br /&gt;
&lt;br /&gt;
A typical motion output consists of:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sub-001_ses-01_task-motor_run-01_tracksys-unknown_motion.tsv&lt;br /&gt;
sub-001_ses-01_task-motor_run-01_tracksys-unknown_motion.json&lt;br /&gt;
sub-001_ses-01_task-motor_run-01_tracksys-unknown_channels.tsv&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The motion TSV is headerless.&lt;br /&gt;
&lt;br /&gt;
Column information is stored in the motion channels TSV:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
name    type    units    description&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A motion mapping may define:&lt;br /&gt;
&lt;br /&gt;
* Column name.&lt;br /&gt;
* Motion type.&lt;br /&gt;
* Units.&lt;br /&gt;
* Description.&lt;br /&gt;
&lt;br /&gt;
The associated JSON sidecar records information such as:&lt;br /&gt;
&lt;br /&gt;
* Sampling frequency.&lt;br /&gt;
* Start time.&lt;br /&gt;
* Column order.&lt;br /&gt;
* Tracking-system name.&lt;br /&gt;
&lt;br /&gt;
All motion states in one output file must contain the same number of samples.&lt;br /&gt;
&lt;br /&gt;
==Neural Signal Conversion==&lt;br /&gt;
&lt;br /&gt;
When neural export is enabled, BCI2000 signal channels are exported as EDF.&lt;br /&gt;
&lt;br /&gt;
The converter currently supports:&lt;br /&gt;
&lt;br /&gt;
* EEG EDF output.&lt;br /&gt;
* iEEG EDF output.&lt;br /&gt;
&lt;br /&gt;
The BCI2000 signal matrix is read with calibration gains applied and converted into the orientation required by the output writer.&lt;br /&gt;
&lt;br /&gt;
A corresponding BIDS channel table contains:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
name    type    units&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For EEG, channels normally use the BIDS channel type:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
EEG&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For iEEG, the channel type is selected from:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
ECOG&lt;br /&gt;
SEEG&lt;br /&gt;
DBS&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The electrophysiology JSON sidecar includes information such as:&lt;br /&gt;
&lt;br /&gt;
* Task name.&lt;br /&gt;
* Sampling frequency.&lt;br /&gt;
* Recording duration.&lt;br /&gt;
* Reference.&lt;br /&gt;
* Source system.&lt;br /&gt;
* Conversion software.&lt;br /&gt;
&lt;br /&gt;
The source system is identified as:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
BCI2000&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The conversion software is identified as:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
bci2000-bids&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Installation==&lt;br /&gt;
&lt;br /&gt;
===Requirements===&lt;br /&gt;
&lt;br /&gt;
Python &amp;#039;&amp;#039;&amp;#039;3.10 or newer&amp;#039;&amp;#039;&amp;#039; is required.&lt;br /&gt;
&lt;br /&gt;
The primary Python dependencies are:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;numpy&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;pyEDFlib&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;PyYAML&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;BCI2000Tools&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Tkinter is required for the graphical interface.&lt;br /&gt;
&lt;br /&gt;
===Recommended Installation===&lt;br /&gt;
&lt;br /&gt;
From a local checkout of the repository, create a Python virtual environment.&lt;br /&gt;
&lt;br /&gt;
On macOS or Linux:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
python3 -m venv .venv&lt;br /&gt;
source .venv/bin/activate&lt;br /&gt;
&lt;br /&gt;
python -m pip install --upgrade pip&lt;br /&gt;
python -m pip install -r requirements.txt&lt;br /&gt;
python -m pip install -e .&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
On Windows PowerShell:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
py -3.14 -m venv .venv&lt;br /&gt;
.venv\Scripts\Activate.ps1&lt;br /&gt;
&lt;br /&gt;
python -m pip install --upgrade pip&lt;br /&gt;
python -m pip install -r requirements.txt&lt;br /&gt;
python -m pip install -e .&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The package also defines installation extras for BCI2000 and YAML support:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
python -m pip install -e &amp;quot;.[yaml,bci2000]&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For development:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
python -m pip install -e &amp;quot;.[yaml,bci2000,dev]&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
On Debian or Ubuntu systems, Tkinter may need to be installed separately:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sudo apt install python3-tk&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The external BIDS Validator is not installed automatically with the Python package.&lt;br /&gt;
&lt;br /&gt;
==Graphical Interface==&lt;br /&gt;
&lt;br /&gt;
The graphical interface may be launched with:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
bci2000-bids-gui&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
or:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
python -m bci2000_bids.gui&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
It may also be launched from the main command:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
bci2000-bids gui&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The GUI supports:&lt;br /&gt;
&lt;br /&gt;
* Selecting one or more &amp;lt;code&amp;gt;.dat&amp;lt;/code&amp;gt; files.&lt;br /&gt;
* Selecting an input directory.&lt;br /&gt;
* Recursive input discovery.&lt;br /&gt;
* Selecting a BIDS output directory.&lt;br /&gt;
* Subject label entry.&lt;br /&gt;
* Session label entry.&lt;br /&gt;
* Task label entry.&lt;br /&gt;
* Behavioral, EEG, or iEEG datatype selection.&lt;br /&gt;
* ECoG, SEEG, or DBS iEEG channel-type selection.&lt;br /&gt;
* Enabling or disabling neural export.&lt;br /&gt;
* Loading an existing profile.&lt;br /&gt;
* Creating a profile using an interactive state-routing editor.&lt;br /&gt;
* Automatic starter-profile generation.&lt;br /&gt;
* Source preservation.&lt;br /&gt;
* SHA-256 checksum generation.&lt;br /&gt;
* Existing-output policy selection.&lt;br /&gt;
* Recording inspection.&lt;br /&gt;
* Dry runs.&lt;br /&gt;
* Conversion.&lt;br /&gt;
* Optional BIDS validation.&lt;br /&gt;
* Progress and status reporting.&lt;br /&gt;
&lt;br /&gt;
The default GUI configuration uses:&lt;br /&gt;
&lt;br /&gt;
* Session &amp;lt;code&amp;gt;01&amp;lt;/code&amp;gt;.&lt;br /&gt;
* Datatype &amp;lt;code&amp;gt;beh&amp;lt;/code&amp;gt;.&lt;br /&gt;
* Neural export disabled.&lt;br /&gt;
* BIDS validation enabled.&lt;br /&gt;
* Existing-output policy &amp;lt;code&amp;gt;error&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==Command-Line Interface==&lt;br /&gt;
&lt;br /&gt;
The command-line program is:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
bci2000-bids&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The equivalent module invocation is:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
python -m bci2000_bids&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The primary commands are:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
inspect&lt;br /&gt;
convert&lt;br /&gt;
profile&lt;br /&gt;
validate&lt;br /&gt;
gui&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Inspect===&lt;br /&gt;
&lt;br /&gt;
To inspect one BCI2000 recording without converting it:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
bci2000-bids inspect recording.dat&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Inspection reports information including:&lt;br /&gt;
&lt;br /&gt;
* File name.&lt;br /&gt;
* Resolved path.&lt;br /&gt;
* Recording duration.&lt;br /&gt;
* Sampling frequency.&lt;br /&gt;
* Number of channels.&lt;br /&gt;
* Number of samples.&lt;br /&gt;
* Channel names.&lt;br /&gt;
* State names.&lt;br /&gt;
* State bit widths.&lt;br /&gt;
* Selected BCI2000 parameters.&lt;br /&gt;
&lt;br /&gt;
Selected parameters include:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;SamplingRate&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;DataFormat&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;Application&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;SignalSource&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;ChannelNames&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;SourceChUnits&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Generate a Profile===&lt;br /&gt;
&lt;br /&gt;
A starter state-routing profile may be generated with:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
bci2000-bids profile recording.dat --output profile.json&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If &amp;lt;code&amp;gt;--output&amp;lt;/code&amp;gt; is omitted, the generated JSON profile is printed to standard output.&lt;br /&gt;
&lt;br /&gt;
The profile should be reviewed before conversion.&lt;br /&gt;
&lt;br /&gt;
===Basic Conversion===&lt;br /&gt;
&lt;br /&gt;
A basic iEEG conversion is:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
bci2000-bids convert recording.dat \&lt;br /&gt;
  --output bids \&lt;br /&gt;
  --subject 001 \&lt;br /&gt;
  --session 01 \&lt;br /&gt;
  --task motor \&lt;br /&gt;
  --datatype ieeg \&lt;br /&gt;
  --channel-type ECOG&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Behavioral/State-Only Conversion===&lt;br /&gt;
&lt;br /&gt;
To convert states without neural data:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
bci2000-bids convert recording.dat \&lt;br /&gt;
  --output bids \&lt;br /&gt;
  --subject 001 \&lt;br /&gt;
  --session 01 \&lt;br /&gt;
  --task motor \&lt;br /&gt;
  --datatype beh \&lt;br /&gt;
  --no-neural \&lt;br /&gt;
  --profile profile.json&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Directory Conversion===&lt;br /&gt;
&lt;br /&gt;
To recursively discover BCI2000 files:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
bci2000-bids convert incoming/ \&lt;br /&gt;
  --output bids/ \&lt;br /&gt;
  --subject 001 \&lt;br /&gt;
  --session 01 \&lt;br /&gt;
  --task motor \&lt;br /&gt;
  --datatype eeg \&lt;br /&gt;
  --recursive&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Source Preservation===&lt;br /&gt;
&lt;br /&gt;
To retain the original BCI2000 recordings:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
bci2000-bids convert recording.dat \&lt;br /&gt;
  --output bids \&lt;br /&gt;
  --subject 001 \&lt;br /&gt;
  --session 01 \&lt;br /&gt;
  --task motor \&lt;br /&gt;
  --datatype ieeg \&lt;br /&gt;
  --channel-type ECOG \&lt;br /&gt;
  --profile profile.json \&lt;br /&gt;
  --preserve-source&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Validation During Conversion===&lt;br /&gt;
&lt;br /&gt;
To run BIDS validation before publishing the converted dataset:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
bci2000-bids convert recording.dat \&lt;br /&gt;
  --output bids \&lt;br /&gt;
  --subject 001 \&lt;br /&gt;
  --session 01 \&lt;br /&gt;
  --task motor \&lt;br /&gt;
  --datatype ieeg \&lt;br /&gt;
  --channel-type ECOG \&lt;br /&gt;
  --validate&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Dry Run===&lt;br /&gt;
&lt;br /&gt;
A conversion may be checked without publishing the final dataset using:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
--dry-run&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A dry run performs discovery, profile/configuration resolution, run assignment, and destination checking without publishing the final converted dataset.&lt;br /&gt;
&lt;br /&gt;
===Debug Logging===&lt;br /&gt;
&lt;br /&gt;
The global debugging option is:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
bci2000-bids --debug ...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;--debug&amp;lt;/code&amp;gt; must appear before the subcommand.&lt;br /&gt;
&lt;br /&gt;
==Typical Workflow==&lt;br /&gt;
&lt;br /&gt;
A typical command-line workflow is:&lt;br /&gt;
&lt;br /&gt;
===1. Inspect the recording===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
bci2000-bids inspect recording.dat&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===2. Generate a starter profile===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
bci2000-bids profile recording.dat --output profile.json&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===3. Review the profile===&lt;br /&gt;
&lt;br /&gt;
Inspect the generated state mappings and confirm that each BCI2000 state has been assigned to the correct scientific role.&lt;br /&gt;
&lt;br /&gt;
In particular, confirm which states represent:&lt;br /&gt;
&lt;br /&gt;
* Experimental events.&lt;br /&gt;
* Event metadata.&lt;br /&gt;
* Continuous behavioral or motion signals.&lt;br /&gt;
* States that should be ignored.&lt;br /&gt;
&lt;br /&gt;
===4. Perform a dry run===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
bci2000-bids convert recording.dat \&lt;br /&gt;
  --output bids \&lt;br /&gt;
  --subject 001 \&lt;br /&gt;
  --session 01 \&lt;br /&gt;
  --task motor \&lt;br /&gt;
  --datatype ieeg \&lt;br /&gt;
  --channel-type ECOG \&lt;br /&gt;
  --profile profile.json \&lt;br /&gt;
  --dry-run&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===5. Convert===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
bci2000-bids convert recording.dat \&lt;br /&gt;
  --output bids \&lt;br /&gt;
  --subject 001 \&lt;br /&gt;
  --session 01 \&lt;br /&gt;
  --task motor \&lt;br /&gt;
  --datatype ieeg \&lt;br /&gt;
  --channel-type ECOG \&lt;br /&gt;
  --profile profile.json \&lt;br /&gt;
  --preserve-source&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===6. Validate===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
bci2000-bids validate bids/&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Configuration Files==&lt;br /&gt;
&lt;br /&gt;
In addition to state-routing profiles, general conversion settings may be stored in JSON or YAML configuration files.&lt;br /&gt;
&lt;br /&gt;
A configuration may contain fields such as:&lt;br /&gt;
&lt;br /&gt;
* Subject.&lt;br /&gt;
* Session.&lt;br /&gt;
* Task.&lt;br /&gt;
* Datatype.&lt;br /&gt;
* Neural export.&lt;br /&gt;
* iEEG channel type.&lt;br /&gt;
* Source preservation.&lt;br /&gt;
* Existing-output behavior.&lt;br /&gt;
* Profile path.&lt;br /&gt;
&lt;br /&gt;
For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
subject: &amp;quot;001&amp;quot;&lt;br /&gt;
session: &amp;quot;01&amp;quot;&lt;br /&gt;
task: &amp;quot;motor&amp;quot;&lt;br /&gt;
datatype: &amp;quot;beh&amp;quot;&lt;br /&gt;
preserve_source: true&lt;br /&gt;
profile: &amp;quot;generic-motion.yaml&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A configuration may be supplied with:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
bci2000-bids convert recording.dat \&lt;br /&gt;
  --output bids \&lt;br /&gt;
  --config examples/configs/study.yaml&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Command-line configuration handling is still under development. Explicit &amp;lt;code&amp;gt;--subject&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;--task&amp;lt;/code&amp;gt; arguments should currently be supplied for reliable noninteractive CLI use.&lt;br /&gt;
&lt;br /&gt;
==Existing Output Handling==&lt;br /&gt;
&lt;br /&gt;
The converter protects existing BIDS data by default.&lt;br /&gt;
&lt;br /&gt;
The existing-output policy may be selected using:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
--on-existing&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Supported values are:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Value&lt;br /&gt;
! Behavior&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;error&amp;lt;/code&amp;gt;&lt;br /&gt;
| Default. Stop if the target subject/session already exists.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;skip&amp;lt;/code&amp;gt;&lt;br /&gt;
| Leave the existing subject/session unchanged and skip conversion.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;overwrite&amp;lt;/code&amp;gt;&lt;br /&gt;
| Rebuild the requested subject/session while retaining other dataset content.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The default policy is:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
error&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Source Data Preservation==&lt;br /&gt;
&lt;br /&gt;
When:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
--preserve-source&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
is enabled, the original BCI2000 recording is copied to:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sourcedata/sub-&amp;lt;subject&amp;gt;/ses-&amp;lt;session&amp;gt;/bci2000/&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sourcedata/sub-001/ses-01/bci2000/recording.dat&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A SHA-256 checksum manifest is written as:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sourcedata/sub-001/ses-01/bci2000/checksums.tsv&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
with columns:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
filename    sha256&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The preserved BCI2000 files are copies of the original recordings and are &amp;#039;&amp;#039;&amp;#039;not anonymized by the converter&amp;#039;&amp;#039;&amp;#039;.&lt;br /&gt;
&lt;br /&gt;
Users should therefore review BCI2000 parameters and other source metadata before distributing &amp;lt;code&amp;gt;sourcedata/&amp;lt;/code&amp;gt; outside the research environment.&lt;br /&gt;
&lt;br /&gt;
==Data Safety==&lt;br /&gt;
&lt;br /&gt;
Conversions are built in a temporary staging directory rather than directly modifying the published BIDS dataset.&lt;br /&gt;
&lt;br /&gt;
When updating an existing dataset:&lt;br /&gt;
&lt;br /&gt;
# The current dataset is copied into a staging location.&lt;br /&gt;
# New conversion output is created in staging.&lt;br /&gt;
# Validation may be performed against the staged dataset.&lt;br /&gt;
# The original dataset is retained until processing succeeds.&lt;br /&gt;
# The staged dataset is moved into place after successful conversion.&lt;br /&gt;
&lt;br /&gt;
When replacement of an existing output root is necessary, the current output is temporarily renamed to a backup location before publication of the staged dataset.&lt;br /&gt;
&lt;br /&gt;
If publication fails, the converter attempts to restore the previous dataset.&lt;br /&gt;
&lt;br /&gt;
EDF files are also created through temporary output before final replacement.&lt;br /&gt;
&lt;br /&gt;
Additional input checks include rejection of:&lt;br /&gt;
&lt;br /&gt;
* Duplicate input basenames.&lt;br /&gt;
* Invalid subject labels.&lt;br /&gt;
* Invalid session labels.&lt;br /&gt;
* Invalid task labels.&lt;br /&gt;
* Invalid tracking-system names.&lt;br /&gt;
* Invalid iEEG channel types.&lt;br /&gt;
* Missing states required by a profile.&lt;br /&gt;
* Invalid signal dimensions.&lt;br /&gt;
* Duplicate or invalid EDF channel labels.&lt;br /&gt;
* Nonfinite neural samples.&lt;br /&gt;
* Certain EDF-incompatible signal conditions.&lt;br /&gt;
&lt;br /&gt;
==BIDS Validation==&lt;br /&gt;
&lt;br /&gt;
The converter includes an optional validation step.&lt;br /&gt;
&lt;br /&gt;
To validate an existing converted dataset:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
bci2000-bids validate bids/&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The converter first performs basic internal checks, including confirming that:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
dataset_description.json&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
exists and contains valid JSON.&lt;br /&gt;
&lt;br /&gt;
When available, it then invokes the external BIDS Validator.&lt;br /&gt;
&lt;br /&gt;
The [https://bids-standard.github.io/bids-validator/ official BIDS Validator] may also be used independently.&lt;br /&gt;
&lt;br /&gt;
When validation is enabled during conversion, validation occurs against the staged dataset before it is published. A validation failure therefore prevents the invalid staged conversion from replacing the existing output dataset.&lt;br /&gt;
&lt;br /&gt;
The external validator must currently be installed separately.&lt;br /&gt;
&lt;br /&gt;
==Clinical and Participant Metadata==&lt;br /&gt;
&lt;br /&gt;
The converter currently handles operational BIDS identifiers and recording metadata such as:&lt;br /&gt;
&lt;br /&gt;
* Participant identifier.&lt;br /&gt;
* Session identifier.&lt;br /&gt;
* Task.&lt;br /&gt;
* Datatype.&lt;br /&gt;
* Run number.&lt;br /&gt;
* Sampling frequency.&lt;br /&gt;
* Recording duration.&lt;br /&gt;
* Channel names.&lt;br /&gt;
* Channel units.&lt;br /&gt;
* Neural channel type.&lt;br /&gt;
* Reference information.&lt;br /&gt;
* Motion tracking-system name.&lt;br /&gt;
&lt;br /&gt;
The converter does &amp;#039;&amp;#039;&amp;#039;not&amp;#039;&amp;#039;&amp;#039; currently automatically extract or request study-specific clinical metadata such as:&lt;br /&gt;
&lt;br /&gt;
* Diagnosis.&lt;br /&gt;
* Age.&lt;br /&gt;
* Sex.&lt;br /&gt;
* Handedness.&lt;br /&gt;
* Surgical procedure.&lt;br /&gt;
* Medication state.&lt;br /&gt;
* DBS stimulation state.&lt;br /&gt;
* Implant target.&lt;br /&gt;
* Recording location.&lt;br /&gt;
* Participant name.&lt;br /&gt;
* Medical record number.&lt;br /&gt;
* Date of birth.&lt;br /&gt;
&lt;br /&gt;
Such metadata must be handled separately when required by a study.&lt;br /&gt;
&lt;br /&gt;
==Limitations==&lt;br /&gt;
&lt;br /&gt;
The current version is focused specifically on converting BCI2000 recordings and synchronized states into electrophysiology, behavioral, event, and motion components of BIDS.&lt;br /&gt;
&lt;br /&gt;
The following are not currently supported:&lt;br /&gt;
&lt;br /&gt;
* Imaging conversion.&lt;br /&gt;
* Video conversion.&lt;br /&gt;
* NeuroOmega file conversion.&lt;br /&gt;
* Automatic ingestion of BCI2000 companion files.&lt;br /&gt;
* Modalities other than &amp;lt;code&amp;gt;beh&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;eeg&amp;lt;/code&amp;gt;, and &amp;lt;code&amp;gt;ieeg&amp;lt;/code&amp;gt;.&lt;br /&gt;
* BrainVision output.&lt;br /&gt;
* FIF output.&lt;br /&gt;
* NIfTI output.&lt;br /&gt;
* Automatic grouping of recordings using BCI2000 recording metadata.&lt;br /&gt;
* Comprehensive export of every BCI2000 parameter into BIDS metadata.&lt;br /&gt;
* Automatic extraction of clinical or surgical metadata.&lt;br /&gt;
* Automatic anonymization of preserved BCI2000 source files.&lt;br /&gt;
* Automatic generation of &amp;lt;code&amp;gt;.bidsignore&amp;lt;/code&amp;gt;.&lt;br /&gt;
* General provenance manifests beyond source checksums and generated conversion profiles.&lt;br /&gt;
&lt;br /&gt;
Automatic state classification is heuristic and should not be treated as a substitute for knowledge of the experiment.&lt;br /&gt;
&lt;br /&gt;
==Development and Testing==&lt;br /&gt;
&lt;br /&gt;
The project contains unit and integration tests for core conversion functionality.&lt;br /&gt;
&lt;br /&gt;
Current automated testing covers areas including:&lt;br /&gt;
&lt;br /&gt;
* BIDS dataset initialization.&lt;br /&gt;
* Dataset descriptions.&lt;br /&gt;
* Participant-table creation.&lt;br /&gt;
* BIDS label normalization.&lt;br /&gt;
* BIDS run naming.&lt;br /&gt;
* Rising-edge event generation.&lt;br /&gt;
* Interval event generation.&lt;br /&gt;
* State-change event generation.&lt;br /&gt;
* Motion TSV output.&lt;br /&gt;
* Motion channel definitions.&lt;br /&gt;
* Duplicate state-routing rejection.&lt;br /&gt;
* BCI2000 parameter parsing utilities.&lt;br /&gt;
* Deterministic input discovery.&lt;br /&gt;
* Recursive input discovery.&lt;br /&gt;
* Synthetic state/event conversion.&lt;br /&gt;
* Synthetic iEEG EDF conversion.&lt;br /&gt;
* EDF read-back using pyEDFlib.&lt;br /&gt;
* Missing-unit fallback behavior.&lt;br /&gt;
&lt;br /&gt;
The current integration tests use synthetic/mock BCI2000 recordings rather than decoding real clinical or experimental BCI2000 files.&lt;br /&gt;
&lt;br /&gt;
Real BCI2000 files should therefore be tested and reviewed in the intended research environment before relying on a new conversion workflow for production datasets.&lt;br /&gt;
&lt;br /&gt;
==BIDS Background==&lt;br /&gt;
&lt;br /&gt;
[https://bids.neuroimaging.io/ BIDS] is a community-developed standard for organizing neural and associated experimental data in a consistent filesystem structure.&lt;br /&gt;
&lt;br /&gt;
A typical BIDS hierarchy follows the general form:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
dataset/&lt;br /&gt;
└── sub-&amp;lt;subject&amp;gt;/&lt;br /&gt;
    └── ses-&amp;lt;session&amp;gt;/&lt;br /&gt;
        └── &amp;lt;datatype&amp;gt;/&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Within this structure, file names encode entities such as subject, session, task, and run.&lt;br /&gt;
&lt;br /&gt;
The BCI2000 to BIDS Converter performs this transformation automatically for supported BCI2000 data while retaining synchronization between neural signals and selected BCI2000 states.&lt;br /&gt;
&lt;br /&gt;
For the complete standard, see the [https://bids-specification.readthedocs.io/en/stable/ BIDS Specification].&lt;br /&gt;
&lt;br /&gt;
==References==&lt;br /&gt;
&lt;br /&gt;
# Gorgolewski KJ, Auer T, Calhoun VD, et al. [https://doi.org/10.1038/sdata.2016.44 The brain imaging data structure, a format for organizing and describing outputs of neuroimaging experiments]. &amp;#039;&amp;#039;Scientific Data&amp;#039;&amp;#039;. 2016;3:160044. doi:10.1038/sdata.2016.44.&lt;br /&gt;
# [https://bids.neuroimaging.io/ Brain Imaging Data Structure (BIDS)].&lt;br /&gt;
# [https://bids-specification.readthedocs.io/en/stable/ BIDS Specification].&lt;br /&gt;
# [https://bids-standard.github.io/bids-validator/ BIDS Validator].&lt;br /&gt;
&lt;br /&gt;
==See also==&lt;br /&gt;
&lt;br /&gt;
* [[Technical Reference:BCI2000 File Format|BCI2000 File Format]]&lt;br /&gt;
* [[User Reference:Data File Formats|BCI2000 Data File Formats]]&lt;br /&gt;
* [[User Reference:BCI2000Export|BCI2000Export]]&lt;br /&gt;
* [[User Reference:Command Line Processing|BCI2000 Command Line Processing]]&lt;br /&gt;
* [[BCI2000Tools.EventRelated|BCI2000Tools and Python Data Analysis]]&lt;br /&gt;
* [[User Tutorial:Data Analysis|BCI2000 Data Analysis Tutorials]]&lt;br /&gt;
* [https://bids.neuroimaging.io/ Brain Imaging Data Structure]&lt;br /&gt;
* [https://bids-specification.readthedocs.io/en/stable/ BIDS Specification]&lt;br /&gt;
* [https://bids-standard.github.io/bids-validator/ BIDS Validator]&lt;br /&gt;
&lt;br /&gt;
[[Category:Data Analysis Tools]]&lt;/div&gt;</description>
			<pubDate>Mon, 28 Sep 2026 23:58:39 GMT</pubDate>
			<dc:creator>Aes2376</dc:creator>
			<comments>https://www.bci2000.org/mediawiki/index.php/Talk:BCI2000_to_BIDS_Converter</comments>
		</item>
		<item>
			<title>Contributions:NetworkHID</title>
			<link>https://www.bci2000.org/mediawiki/index.php?title=Contributions:NetworkHID&amp;diff=12606&amp;oldid=12601</link>
			<guid isPermaLink="false">https://www.bci2000.org/mediawiki/index.php?title=Contributions:NetworkHID&amp;diff=12606&amp;oldid=12601</guid>
			<description>&lt;p&gt;&lt;/p&gt;
&lt;table style=&quot;background-color: #fff; color: #202122;&quot; data-mw=&quot;interface&quot;&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;tr class=&quot;diff-title&quot; lang=&quot;en&quot;&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;← Older revision&lt;/td&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;Revision as of 04:39, 26 September 2026&lt;/td&gt;
				&lt;/tr&gt;&lt;tr&gt;&lt;td colspan=&quot;4&quot; class=&quot;diff-multi&quot; lang=&quot;en&quot;&gt;(4 intermediate revisions by the same user not shown)&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot; id=&quot;mw-diff-left-l22&quot;&gt;Line 22:&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 22:&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;A NetworkHID setup consists of one computer running BCI2000, and a microcontroller connected to a target device. The microcontroller acts as a wireless access point, that is, the BCI2000 computer can connect to it over Wi-Fi, and can then send it commands. These commands can direct the microcontroller to press and release keys or mouse buttons, as well as move the mouse of the target device. In this way, BCI2000 can control the target device, either mirroring the keyboard and mouse inputs of the BCI2000 via the extension, or sending inputs in response to BCI2000&amp;#039;s internal state, for example, moving the mouse in accordance with the cursor in a Cursor Task, or entering the chosen letters in a Speller Task.&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;A NetworkHID setup consists of one computer running BCI2000, and a microcontroller connected to a target device. The microcontroller acts as a wireless access point, that is, the BCI2000 computer can connect to it over Wi-Fi, and can then send it commands. These commands can direct the microcontroller to press and release keys or mouse buttons, as well as move the mouse of the target device. In this way, BCI2000 can control the target device, either mirroring the keyboard and mouse inputs of the BCI2000 via the extension, or sending inputs in response to BCI2000&amp;#039;s internal state, for example, moving the mouse in accordance with the cursor in a Cursor Task, or entering the chosen letters in a Speller Task.&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;−&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;===NetworkHID &lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;Device &lt;/del&gt;Details===&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;===NetworkHID &lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;Protocol &lt;/ins&gt;Details===&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;When a computer connects to the microcontroller&amp;#039;s Wi-Fi network, the microcontroller itself will also be present on the network with its own IP address. This address is device-dependent, but on a Pi Pico 2 W, it is &amp;lt;code&amp;gt;192.168.4.1&amp;lt;/code&amp;gt;. It will expose a port (by default &amp;lt;code&amp;gt;1024&amp;lt;/code&amp;gt; as set in &amp;lt;code&amp;gt;code.py&amp;lt;/code&amp;gt;) to receive commands.  &lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;When a computer connects to the microcontroller&amp;#039;s Wi-Fi network, the microcontroller itself will also be present on the network with its own IP address. This address is device-dependent, but on a Pi Pico 2 W, it is &amp;lt;code&amp;gt;192.168.4.1&amp;lt;/code&amp;gt;. It will expose a port (by default &amp;lt;code&amp;gt;1024&amp;lt;/code&amp;gt; as set in &amp;lt;code&amp;gt;code.py&amp;lt;/code&amp;gt;) to receive commands.  &lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot; id=&quot;mw-diff-left-l54&quot;&gt;Line 54:&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 54:&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;These depend on the &amp;#039;&amp;#039;&amp;#039;Type&amp;#039;&amp;#039;&amp;#039;, as detailed below&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;These depend on the &amp;#039;&amp;#039;&amp;#039;Type&amp;#039;&amp;#039;&amp;#039;, as detailed below&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;−&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;=&lt;/del&gt;===NetworkHID Commands&lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;=&lt;/del&gt;===&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;===NetworkHID Commands===&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;These commands use the Adafruit HID library to emulate an HID.&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;These commands use the Adafruit HID library to emulate an HID.&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot; id=&quot;mw-diff-left-l71&quot;&gt;Line 71:&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 71:&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;=====Mouse Button=====&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;=====Mouse Button=====&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;Press or release mouse buttons. &amp;#039;&amp;#039;&amp;#039;Arg1&amp;#039;&amp;#039;&amp;#039; and &amp;#039;&amp;#039;&amp;#039;Arg2&amp;#039;&amp;#039;&amp;#039; correspond to buttons Mouse 1 and Mouse 2. If the argument is 1, the button is pressed, and if the argument is 0, the button is released.&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;Press or release mouse buttons. &amp;#039;&amp;#039;&amp;#039;Arg1&amp;#039;&amp;#039;&amp;#039; and &amp;#039;&amp;#039;&amp;#039;Arg2&amp;#039;&amp;#039;&amp;#039; correspond to buttons Mouse 1 and Mouse 2. If the argument is 1, the button is pressed, and if the argument is 0, the button is released.&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;−&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;&lt;/del&gt;&lt;/div&gt;&lt;/td&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-added&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;==Building a NetworkHID device==&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;==Building a NetworkHID device==&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot; id=&quot;mw-diff-left-l77&quot;&gt;Line 77:&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 76:&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;The NetworkHID CircuitPython code has been tested with a Raspberry Pi Pico 2 W microcontroller, although theoretically it should work on any device which supports CircuitPython and is capable of acting as a wireless access point.  &lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;The NetworkHID CircuitPython code has been tested with a Raspberry Pi Pico 2 W microcontroller, although theoretically it should work on any device which supports CircuitPython and is capable of acting as a wireless access point.  &lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;−&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;Acquire a microcontroller and &lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;install CircuitPython onto it &lt;/del&gt;[https://learn.adafruit.com/welcome-to-circuitpython/installing-circuitpython].&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;Acquire a microcontroller and [https://learn.adafruit.com/welcome-to-circuitpython/installing-circuitpython &lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;install CircuitPython on it&lt;/ins&gt;].&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;−&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;After installing CircuitPython, the microcontroller should appear as a storage device when plugged into your computer. Copy the &amp;lt;code&amp;gt;code.py&amp;lt;/code&amp;gt; file into the device, replacing the existing one. (This file can be found within the BCI2000 source code at &amp;lt;code&amp;gt;src/extlib/NetworkHID/code.py&amp;lt;/code&amp;gt;. Alternatively, it is also located externally at &lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;[&lt;/del&gt;https://codeberg.org/personator01/bci2000-nethid&lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;]&lt;/del&gt;.&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;After installing CircuitPython, the microcontroller should appear as a storage device when plugged into your computer. Copy the &amp;lt;code&amp;gt;code.py&amp;lt;/code&amp;gt; file into the device, replacing the existing one. (This file can be found within the BCI2000 source code at &amp;lt;code&amp;gt;src/extlib/NetworkHID/code.py&amp;lt;/code&amp;gt;. Alternatively, it is also located externally at https://codeberg.org/personator01/bci2000-nethid.&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;Once you plug the microcontroller into the target device, it will begin to act as a wireless access point. It will host a Wi-Fi network, with default name &amp;lt;code&amp;gt;&amp;quot;pico&amp;quot;&amp;lt;/code&amp;gt; and default password &amp;lt;code&amp;gt;&amp;quot;pass12345&amp;quot;&amp;lt;/code&amp;gt; (these values can be changed by editing the &amp;lt;code&amp;gt;code.py&amp;lt;/code&amp;gt; file). On the BCI2000 computer, connect to this Wi-Fi network.&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;Once you plug the microcontroller into the target device, it will begin to act as a wireless access point. It will host a Wi-Fi network, with default name &amp;lt;code&amp;gt;&amp;quot;pico&amp;quot;&amp;lt;/code&amp;gt; and default password &amp;lt;code&amp;gt;&amp;quot;pass12345&amp;quot;&amp;lt;/code&amp;gt; (these values can be changed by editing the &amp;lt;code&amp;gt;code.py&amp;lt;/code&amp;gt; file). On the BCI2000 computer, connect to this Wi-Fi network.&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot; id=&quot;mw-diff-left-l113&quot;&gt;Line 113:&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 112:&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;==Implementing NetworkHID communication within a custom module==&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;==Implementing NetworkHID communication within a custom module==&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;−&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;For behavior beyond just mirroring the keyboard and mouse inputs of the host machine, the NetworkHID can be used from a custom BCI2000 module. The &amp;lt;code&amp;gt;NetworkHID&amp;lt;/code&amp;gt; class provides an interface within BCI2000 for sending commands to the microcontroller. Its interface is located within &amp;lt;code&amp;gt;src/extlib/NetworkHID/NetworkHID.h&amp;lt;/code&amp;gt;. Additionally, the [https://codeberg.org/personator01/bci2000-nethid&lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;|&lt;/del&gt;external git repository for NetworkHID] contains examples of it being used within a custom Cursor Task, and a P3 Speller task.&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;For behavior beyond just mirroring the keyboard and mouse inputs of the host machine, the NetworkHID can be used from a custom BCI2000 module. The &amp;lt;code&amp;gt;NetworkHID&amp;lt;/code&amp;gt; class provides an interface within BCI2000 for sending commands to the microcontroller. Its interface is located within &amp;lt;code&amp;gt;src/extlib/NetworkHID/NetworkHID.h&amp;lt;/code&amp;gt;. Additionally, the [https://codeberg.org/personator01/bci2000-nethid external git repository for NetworkHID] contains examples of it being used within a custom Cursor Task, and a P3 Speller task.&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;

&lt;!-- diff cache key wikidb-bci_:diff:1.41:old-12601:rev-12606:php=table --&gt;
&lt;/table&gt;</description>
			<pubDate>Sat, 26 Sep 2026 04:39:57 GMT</pubDate>
			<dc:creator>Tytbutler</dc:creator>
			<comments>https://www.bci2000.org/mediawiki/index.php/Talk:Contributions:NetworkHID</comments>
		</item>
		<item>
			<title>Contributions:NetworkHID</title>
			<link>https://www.bci2000.org/mediawiki/index.php?title=Contributions:NetworkHID&amp;diff=12601&amp;oldid=0</link>
			<guid isPermaLink="false">https://www.bci2000.org/mediawiki/index.php?title=Contributions:NetworkHID&amp;diff=12601&amp;oldid=0</guid>
			<description>&lt;p&gt;Created page with &amp;quot;==Synopsis==  Functionality for sending commands from BCI2000 to an external USB device which emulates a USB Human Interface Device (HID), that is, a keyboard and mouse. This consists of three components: a snippet of Python code which runs on a CircuitPython-capable microcontroller with Wi-Fi and USB functionality, a C++ class within BCI2000 which provides an interface for sending commands to the microcontroller from within a BCI2000 module, and an BCI2000 extension whi...&amp;quot;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;New page&lt;/b&gt;&lt;/p&gt;&lt;div&gt;==Synopsis==&lt;br /&gt;
&lt;br /&gt;
Functionality for sending commands from BCI2000 to an external USB device which emulates a USB Human Interface Device (HID), that is, a keyboard and mouse. This consists of three components: a snippet of Python code which runs on a CircuitPython-capable microcontroller with Wi-Fi and USB functionality, a C++ class within BCI2000 which provides an interface for sending commands to the microcontroller from within a BCI2000 module, and an BCI2000 extension which mirrors mouse and keyboard from the BCI2000 computer to the microcontroller.&lt;br /&gt;
&lt;br /&gt;
==Location==&lt;br /&gt;
Microcontroller code:&lt;br /&gt;
http://{{SERVERNAME}}/svn/trunk/src/extlib/NetworkHID/code.py&lt;br /&gt;
&lt;br /&gt;
BCI2000 internal interface&lt;br /&gt;
http://{{SERVERNAME}}/svn/trunk/src/extlib/NetworkHID/&lt;br /&gt;
&lt;br /&gt;
BCI2000 Extension&lt;br /&gt;
http://{{SERVERNAME}}/svn/trunk/src/extlib/NetworkHID/&lt;br /&gt;
&lt;br /&gt;
===Authors===&lt;br /&gt;
Ty Butler (butler@neurotechcenter.org)&lt;br /&gt;
&lt;br /&gt;
==Functional Description==&lt;br /&gt;
&lt;br /&gt;
Certain assistive devices allow input only via USB keyboard and mouse. Enabling BCI2000 to send keyboard and mouse inputs allows for the control of these devices by biosignal data. &lt;br /&gt;
&lt;br /&gt;
A NetworkHID setup consists of one computer running BCI2000, and a microcontroller connected to a target device. The microcontroller acts as a wireless access point, that is, the BCI2000 computer can connect to it over Wi-Fi, and can then send it commands. These commands can direct the microcontroller to press and release keys or mouse buttons, as well as move the mouse of the target device. In this way, BCI2000 can control the target device, either mirroring the keyboard and mouse inputs of the BCI2000 via the extension, or sending inputs in response to BCI2000&amp;#039;s internal state, for example, moving the mouse in accordance with the cursor in a Cursor Task, or entering the chosen letters in a Speller Task.&lt;br /&gt;
&lt;br /&gt;
===NetworkHID Device Details===&lt;br /&gt;
&lt;br /&gt;
When a computer connects to the microcontroller&amp;#039;s Wi-Fi network, the microcontroller itself will also be present on the network with its own IP address. This address is device-dependent, but on a Pi Pico 2 W, it is &amp;lt;code&amp;gt;192.168.4.1&amp;lt;/code&amp;gt;. It will expose a port (by default &amp;lt;code&amp;gt;1024&amp;lt;/code&amp;gt; as set in &amp;lt;code&amp;gt;code.py&amp;lt;/code&amp;gt;) to receive commands. &lt;br /&gt;
&lt;br /&gt;
A NetworkHID command consists of 16 bytes, in the following format:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;text-align: center;&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! 0 !! 1 !! 2 !! 3 !! 4 !! 5 !! 6 !! 7 !! 8 !! 9 !! 10 !! 11 !! 12 !! 13 !! 14 !! 15&lt;br /&gt;
|-&lt;br /&gt;
|colspan=&amp;quot;4&amp;quot;|Magic&lt;br /&gt;
|colspan=&amp;quot;4&amp;quot;|Type&lt;br /&gt;
|colspan=&amp;quot;4&amp;quot;|Arg1&lt;br /&gt;
|colspan=&amp;quot;4&amp;quot;|Arg2&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Each of &amp;#039;&amp;#039;&amp;#039;Magic&amp;#039;&amp;#039;&amp;#039;, &amp;#039;&amp;#039;&amp;#039;Type&amp;#039;&amp;#039;&amp;#039;, &amp;#039;&amp;#039;&amp;#039;Arg1&amp;#039;&amp;#039;&amp;#039;, and &amp;#039;&amp;#039;&amp;#039;Arg2&amp;#039;&amp;#039;&amp;#039; is a 32-bit integer in big-endian form. Magic and Type are unsigned, while Arg1 and Arg2 are signed.&lt;br /&gt;
&lt;br /&gt;
=====Magic=====&lt;br /&gt;
The constant value &amp;lt;code&amp;gt;0x0bc12000&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=====Type=====&lt;br /&gt;
The type of command being sent. This can be one of four values:&lt;br /&gt;
&lt;br /&gt;
# &amp;#039;&amp;#039;&amp;#039;Key Press&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
# &amp;#039;&amp;#039;&amp;#039;Key Release&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
# &amp;#039;&amp;#039;&amp;#039;Move Mouse&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
# &amp;#039;&amp;#039;&amp;#039;Mouse Button&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
=====Arg1 and Arg2=====&lt;br /&gt;
These depend on the &amp;#039;&amp;#039;&amp;#039;Type&amp;#039;&amp;#039;&amp;#039;, as detailed below&lt;br /&gt;
&lt;br /&gt;
====NetworkHID Commands====&lt;br /&gt;
&lt;br /&gt;
These commands use the Adafruit HID library to emulate an HID.&lt;br /&gt;
&lt;br /&gt;
=====Key Press=====&lt;br /&gt;
Press a key. Takes &amp;#039;&amp;#039;&amp;#039;Arg1&amp;#039;&amp;#039;&amp;#039; to be an ASCII character value, and presses the corresponding key, or combination of keys, necessary to input the character. The keys will remain held until they are released by a &amp;#039;&amp;#039;&amp;#039;Key Release&amp;#039;&amp;#039;&amp;#039; command. Currently, only ASCII characters are supported, and sending non-ASCII values will cause the device to crash, at which point it must be unplugged and plugged back in, and the client computer must reconnect to its Wi-Fi network.&lt;br /&gt;
&lt;br /&gt;
=====Key Release=====&lt;br /&gt;
Release the keys corresponding to the ASCII key value given by &amp;#039;&amp;#039;&amp;#039;Arg1&amp;#039;&amp;#039;&amp;#039;.&lt;br /&gt;
&lt;br /&gt;
=====Move Mouse=====&lt;br /&gt;
Move the mouse by (&amp;#039;&amp;#039;&amp;#039;Arg1&amp;#039;&amp;#039;&amp;#039;,&amp;#039;&amp;#039;&amp;#039;Arg2&amp;#039;&amp;#039;&amp;#039;) units. The movement is relative to the current position of the mouse, and the units are those defined by the Adafruit HID library. &lt;br /&gt;
&lt;br /&gt;
Due to limitations of the library, these values are clamped to the range (-100,100). In practice, if you are implementing precise control of the mouse using the NetworkHID, you will need to test until you find suitable movement values. Additionally, due to the relative nature of mouse movement, it may be difficult to maintain a consistent mouse position. The workaround for this is, when you need the mouse in a precise location, to move it to the top left corner of the screen to establish a known position by repeatedly sending &amp;#039;&amp;#039;&amp;#039;Mouse Move&amp;#039;&amp;#039;&amp;#039; commands with parameter (-100,100), and then moving the mouse to the desired location.&lt;br /&gt;
&lt;br /&gt;
=====Mouse Button=====&lt;br /&gt;
Press or release mouse buttons. &amp;#039;&amp;#039;&amp;#039;Arg1&amp;#039;&amp;#039;&amp;#039; and &amp;#039;&amp;#039;&amp;#039;Arg2&amp;#039;&amp;#039;&amp;#039; correspond to buttons Mouse 1 and Mouse 2. If the argument is 1, the button is pressed, and if the argument is 0, the button is released.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Building a NetworkHID device==&lt;br /&gt;
&lt;br /&gt;
The NetworkHID CircuitPython code has been tested with a Raspberry Pi Pico 2 W microcontroller, although theoretically it should work on any device which supports CircuitPython and is capable of acting as a wireless access point. &lt;br /&gt;
&lt;br /&gt;
Acquire a microcontroller and install CircuitPython onto it [https://learn.adafruit.com/welcome-to-circuitpython/installing-circuitpython].&lt;br /&gt;
&lt;br /&gt;
After installing CircuitPython, the microcontroller should appear as a storage device when plugged into your computer. Copy the &amp;lt;code&amp;gt;code.py&amp;lt;/code&amp;gt; file into the device, replacing the existing one. (This file can be found within the BCI2000 source code at &amp;lt;code&amp;gt;src/extlib/NetworkHID/code.py&amp;lt;/code&amp;gt;. Alternatively, it is also located externally at [https://codeberg.org/personator01/bci2000-nethid].&lt;br /&gt;
&lt;br /&gt;
Once you plug the microcontroller into the target device, it will begin to act as a wireless access point. It will host a Wi-Fi network, with default name &amp;lt;code&amp;gt;&amp;quot;pico&amp;quot;&amp;lt;/code&amp;gt; and default password &amp;lt;code&amp;gt;&amp;quot;pass12345&amp;quot;&amp;lt;/code&amp;gt; (these values can be changed by editing the &amp;lt;code&amp;gt;code.py&amp;lt;/code&amp;gt; file). On the BCI2000 computer, connect to this Wi-Fi network.&lt;br /&gt;
&lt;br /&gt;
The device is now ready to receive commands from BCI2000.&lt;br /&gt;
&lt;br /&gt;
==The NetworkHID Extension==&lt;br /&gt;
The NetworkHID extension is a source module extension that takes keyboard and mouse inputs made on the BCI2000 computer and mirrors them on the target device, via the NetworkHID microcontroller. It does this by reading the built-in &amp;lt;code&amp;gt;KeyDown&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;KeyUp&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;MousePosX&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;MousePosY&amp;lt;/code&amp;gt;, and &amp;lt;code&amp;gt;MouseKeys&amp;lt;/code&amp;gt; state variables, detecting when they have changed, and translating them into commands sent over the network to the microcontroller. Due to the synchronous nature of BCI2000, this happens once per sample block processing loop.&lt;br /&gt;
&lt;br /&gt;
It is compiled by enabling the &amp;lt;code&amp;gt;EXTENSIONS_NETWORKHIDEXTENSION&amp;lt;/code&amp;gt; CMake variable during the BCI2000 [[Programming Howto:Configure BCI2000 for Compilation|build process]] (If you have not build BCI2000 from source before, follow the instructions in [[Programming Howto:Building and Customizing BCI2000]]).&lt;br /&gt;
&lt;br /&gt;
Once compiled, the NetworkHID Extension can be enabled by adding the &amp;lt;code&amp;gt;--EnableNetworkHIDLogging&amp;lt;/code&amp;gt; flag to the source module in your BCI2000 startup script. &lt;br /&gt;
&lt;br /&gt;
===Parameters===&lt;br /&gt;
&lt;br /&gt;
=====EnableKeyboardLogging=====&lt;br /&gt;
Send keystrokes from the BCI2000 computer to the microcontroller. &lt;br /&gt;
Default: 1 (true)&lt;br /&gt;
=====EnableMouseMovementLogging=====&lt;br /&gt;
Send mouse movements from the BCI2000 computer to the microcontroller.&lt;br /&gt;
Default: 1 (true)&lt;br /&gt;
=====EnableMouseButtonLogging=====&lt;br /&gt;
Send mouse keypresses from the BCI2000 computer to the microcontroller.&lt;br /&gt;
Default: 1 (true)&lt;br /&gt;
=====MouseMovementLoggingScale=====&lt;br /&gt;
This decimal parameter scales the logged mouse movement.&lt;br /&gt;
Default: 1.0&lt;br /&gt;
=====NetworkHIDAddress=====&lt;br /&gt;
The network address of the microcontroller&amp;#039;s input, in &amp;lt;code&amp;gt;ipv4:port&amp;lt;/code&amp;gt; form. On a Pi Pico 2 W with default deployed &amp;lt;code&amp;gt;code.py&amp;lt;/code&amp;gt;, this should be &amp;lt;code&amp;gt;192.168.4.1:1024&amp;lt;/code&amp;gt;.&lt;br /&gt;
Default: &amp;lt;code&amp;gt;192.168.4.1:1024&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Implementing NetworkHID communication within a custom module==&lt;br /&gt;
&lt;br /&gt;
For behavior beyond just mirroring the keyboard and mouse inputs of the host machine, the NetworkHID can be used from a custom BCI2000 module. The &amp;lt;code&amp;gt;NetworkHID&amp;lt;/code&amp;gt; class provides an interface within BCI2000 for sending commands to the microcontroller. Its interface is located within &amp;lt;code&amp;gt;src/extlib/NetworkHID/NetworkHID.h&amp;lt;/code&amp;gt;. Additionally, the [https://codeberg.org/personator01/bci2000-nethid|external git repository for NetworkHID] contains examples of it being used within a custom Cursor Task, and a P3 Speller task.&lt;/div&gt;</description>
			<pubDate>Fri, 25 Sep 2026 11:37:14 GMT</pubDate>
			<dc:creator>Tytbutler</dc:creator>
			<comments>https://www.bci2000.org/mediawiki/index.php/Talk:Contributions:NetworkHID</comments>
		</item>
</channel></rss>