Read, write and convert OpenBCI signal recordings (.raw/.xml/.tag)
Project description
readmanager
Read, write and convert OBCI signal
recordings stored in the OBCI file format (.raw / .xml / .tag).
Installation
pip install readmanager # core (numpy only)
pip install readmanager[mne] # + MNE-Python conversion
pip install readmanager[balance] # + Wii Balance Board analysis (scipy)
pip install readmanager[all] # everything
Requires Python 3.10+.
Quick start
from obci_readmanager.signal_processing.read_manager import ReadManager
# Open a recording (three files: .raw, .xml, .tag)
mgr = ReadManager(
"recording.obci.xml",
"recording.obci.raw",
"recording.obci.tag",
)
# Access signal parameters
print(mgr.get_param("sampling_frequency"))
print(mgr.get_param("channels_names"))
# Get all samples as a numpy array (channels x samples)
samples = mgr.get_samples()
# Get samples for a single channel
fp1 = mgr.get_channel_samples("Fp1")
# Get samples in microvolts (applies gain and offset calibration)
uv = mgr.get_microvolt_samples()
# Iterate over tags (event markers)
for tag in mgr.iter_tags():
print(tag["name"], tag["start_timestamp"])
Smart tags
Smart tags extract signal segments aligned to event markers:
from obci_readmanager.signal_processing.smart_tags_manager import SmartTagsManager
from obci_readmanager.signal_processing.tags.smart_tag_definition import SmartTagDurationDefinition
# Define: 1 second of signal after each "stimulus" tag
tag_def = SmartTagDurationDefinition(
start_tag_name="stimulus",
start_offset=0.0,
end_offset=0.0,
duration=1.0,
)
smart_mgr = SmartTagsManager(
tag_def,
"recording.obci.xml",
"recording.obci.raw",
"recording.obci.tag",
)
for smart_tag in smart_mgr.iter_smart_tags():
data = smart_tag.get_samples() # channels x samples for this epoch
print(data.shape)
MNE-Python conversion
# ReadManager -> MNE Raw
raw_mne = mgr.get_mne_raw()
# MNE Raw -> ReadManager
mgr2 = ReadManager.from_mne(raw_mne)
# Smart tags -> MNE Epochs
epochs = smart_mgr.get_mne_epochs()
Channel type heuristic
When converting to MNE, get_mne_raw() and friends need to assign an
MNE channel type ('eeg', 'eog', 'emg', 'ecg', 'bio', 'stim',
'misc') to every channel. If you pass an explicit channel_types list,
it's used as-is; otherwise readmanager applies a name-based heuristic
via chtype_heuristic(name) from the mne_utils submodule.
The heuristic recognises, in order of priority:
| Rule | Example inputs | Returns |
|---|---|---|
Substring eog |
EOG Left Horiz, VEOG, EOG Fp1-M2 |
eog |
Substring emg |
EMG Chin1, EMG Ant Tibia-0 |
emg |
Substring ecg / ekg |
ECG ECGI, EKG_lead1 |
ecg |
Substring resp / sao2 / spo2 |
Resp Thermistor, SaO2 SaO2 |
bio |
Substring stim / trig / marker / status / sync or prefix sti |
STIM, Trigger, STI 014, STATUS |
stim |
| Tokenised 10-05 position lookup | Fp1, C3, EEG F3-CLE, Fp1-M2, F3-CAR |
eeg |
| Fall-through | anything else (Channel_42, Aux1, Photo) |
misc |
The 10-05 position check tokenises the channel name on any
non-alphanumeric boundary and matches each token against MNE's
standard_1005 montage position set. This catches prefixed/suffixed
variants common in EDF polysomnography recordings (EEG F3-CLE,
EEG Fp1-M2) without false-positives on short position names
embedded in unrelated words (e.g. audio1, Data1, misc3).
Non-EEG substring rules take priority over the position lookup, so
EOG Fp1-M2 (an EOG reference channel using Fp1/M2 as the reference
montage) is correctly typed as eog rather than eeg.
If your recording has channels the heuristic doesn't classify to your taste, pass an explicit list:
raw = mgr.get_mne_raw(channel_types=["eeg"] * 32 + ["ecg", "stim"])
See the chtype_heuristic docstring for the full decision order and
edge cases, and test/signal_processing/test_chtype_heuristic.py for
the complete parametrised test matrix.
OBCI file format
An OBCI recording consists of three files:
| File | Content |
|---|---|
.obci.raw |
Binary signal data (channels interleaved, float64 by default) |
.obci.xml |
Recording metadata: channel names, sampling frequency, gains, offsets |
.obci.tag |
Event markers in XML format (name, timestamp, duration, description) |
Part of the OBCI ecosystem
readmanager is used by OBCI for
signal file replay and post-recording correction. Related packages:
- obci-server — EEG acquisition server (depends on readmanager)
- obci-desktop — desktop launcher and LSL streaming
- obci-psychopy — PsychoPy tag integration
- SVAROG4 — Java signal viewer/recorder
License
GNU General Public License v3 or later (GPLv3+).
Originally developed by BrainTech and the Faculty of Physics, University of Warsaw.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file readmanager-1.4.0.tar.gz.
File metadata
- Download URL: readmanager-1.4.0.tar.gz
- Upload date:
- Size: 43.3 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.0
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
4906f29db2be910914e8a173a5255f95aa0492e20b094eaf57e2ff58aea79ca1
|
|
| MD5 |
ab64c4d53a9a3db7eab3a882a784adc6
|
|
| BLAKE2b-256 |
6416cbca97d4b96e4c690265b1ee4f95f5e32ef482a647f8dd2f4ac666f66d79
|
File details
Details for the file readmanager-1.4.0-py3-none-any.whl.
File metadata
- Download URL: readmanager-1.4.0-py3-none-any.whl
- Upload date:
- Size: 62.5 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.0
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
619981cc5abf58126fbf603e6a292a2d7c4203bafac8d9189eeb8e0916b1eb97
|
|
| MD5 |
6e558dcc668d0aeb7ec541ef08d31868
|
|
| BLAKE2b-256 |
153133557e705207e92c480e4d3999747fa60ce528782d665b6b5ef715f6f785
|