ワンクリックで
openephys
Open Ephys GUI Record Node output (continuous.dat / structure.oebin) — open-source ephys acquisition
Codex または Claude でインストール この Prompt をコピーして Codex、Claude、または他のアシスタントに貼り付けると、Skill ページを確認してインストールできます。
メニュー
Open Ephys GUI Record Node output (continuous.dat / structure.oebin) — open-source ephys acquisition
Codex または Claude でインストール この Prompt をコピーして Codex、Claude、または他のアシスタントに貼り付けると、Skill ページを確認してインストールできます。
SOC 職業分類に基づく
Neurodata Without Borders (.nwb) — the de-facto standard for in-vivo electrophysiology (Neuropixels / AIBS / DANDI / IBL)
Index of L0 data-format loader skills by family
Index of all L2 paradigm skills by group + analysis_goal → paradigm matrix
Two-phase BCI data preprocessing pipeline: deep-inspect → plan → propose → user confirm → automated code/execute/QC/export
BIDS-iEEG sidecar (*_channels.tsv / *_electrodes.tsv / *_coordsystem.json / *_ieeg.json) — clinical sEEG / ECoG standard
Multiscale Electrophysiology Format v3 (Mayo Clinic) — long-duration encrypted sEEG
| name | openephys |
| description | Open Ephys GUI Record Node output (continuous.dat / structure.oebin) — open-source ephys acquisition |
| layer | L0 |
| group | spike_ephys |
| metadata | {"tags":["io","openephys","oebin","continuous","ephys","open_source"],"formats":[".dat",".oebin",".npy",".xml"],"modalities":["spike","lfp","ecog"]} |
Open Ephys is the leading open-source ephys acquisition stack (https://open-ephys.org/), running on commodity hardware (Intan RHD2000 amplifiers, Acquisition Board, Neuropixels via the IMEC plugin). It writes data via a Record Node in one of two binary layouts:
continuous.dat + JSON-based
structure.oebin manifest. Current default since ~2021..continuous per channel +
messages.events + settings.xml. Still found in archived datasets
but deprecated.The binary format is multi-stream — one continuous/<stream_id>/
directory per probe / amplifier, mirroring SpikeGLX's split.
Binary format (0.6+):
experiment1/
recording1/
structure.oebin # JSON manifest (REQUIRED for SpikeInterface readers)
sync_messages.txt
continuous/
Neuropix-PXI-100.ProbeA-AP/
continuous.dat # raw int16, ch-interleaved, 30 kHz AP
sample_numbers.npy
timestamps.npy
Neuropix-PXI-100.ProbeA-LFP/
continuous.dat # 2.5 kHz LFP
sample_numbers.npy
timestamps.npy
events/
Neuropix-PXI-100.ProbeA-AP/TTL/
states.npy
sample_numbers.npy
full_words.npy
Message_Center-904/text_messages/
text.npy
sample_numbers.npy
Legacy format (< 0.6):
experiment1/recording1/
100_CH1.continuous # one file per channel
100_CH2.continuous
...
all_channels.events # TTL events
settings.xml # acquisition config
messages.events # text messages
The structure.oebin JSON manifest is the canonical metadata source.
Required fields:
| JSON path | Type | Meaning |
|---|---|---|
continuous[i].folder_name | str | Subdir under continuous/ containing continuous.dat. |
continuous[i].sample_rate | float | Hz. |
continuous[i].num_channels | int | Channel count (data is ch-interleaved). |
continuous[i].channels[j].name | str | Per-channel label. |
continuous[i].channels[j].bit_volts | float | int16 → volts conversion factor. |
continuous[i].channels[j].units | str | "uV" or "V"; multiply accordingly. |
events[i].folder_name | str | TTL events directory. |
events[i].sample_rate | float | Should match continuous stream. |
structure.oebin exists in 0.6+. Legacy .continuous per-channel files
carry their own embedded header — see open-ephys-python-tools.OpenEphys.loadContinuous.
| Priority | Library | Use case | Lazy install |
|---|---|---|---|
| Primary | SpikeInterface.read_openephys | Schema-aware; handles 0.6+ binary + legacy; auto-detects stream. | spikeinterface==0.101.0 via io.openephys lazy-deps key. |
| Secondary | open-ephys-python-tools (PyPI open-ephys-python-tools) | Open Ephys' own reader; same coverage as SpikeInterface. | pip install open-ephys-python-tools==0.1.10. |
| Tertiary | np.memmap on continuous.dat + manual .oebin JSON parse | Headless / minimal-dep environments. | Built-in. |
Spike (AP-band, Intan / Neuropixels-via-IMEC-plugin): yes. LFP (Intan dedicated LFP board / NPx LF): yes. ECoG (Intan with ECoG headstages): yes. EEG / MEG / fNIRS: no.
KeyError on read, confirm the GUI version that wrote the recording.continuous/<stream>/ dirs. Calling read_openephys without
stream_id=... picks one arbitrarily.bit_volts not always 0.195 µV. Intan-default amplifiers
are 0.195 µV/bit; Neuropixels-via-IMEC-plugin uses ~2.34 µV/bit at
default gain. Always read bit_volts from .oebin.sample_numbers.npy is monotonic
sample indices; timestamps.npy is wall-clock (when synchronized
with the NI-DAQ via the Sync plugin). Use sample_numbers for
intra-stream alignment, timestamps only for cross-rig sync.states array. states.npy is +/− channel IDs:
positive means rising edge, negative means falling. Reconstruct
(channel, rising_or_falling, sample_number) from the trio.recordingX directories. Open Ephys
splits long sessions into 1 GB chunks (default; configurable). Load
with SpikeInterface which concatenates transparently."""Standalone Open Ephys binary-format loader (0.6+)."""
from __future__ import annotations
import json
from dataclasses import dataclass
from pathlib import Path
from typing import Dict, List
import numpy as np
@dataclass
class OpenEphysLoad:
data: np.ndarray # (n_channels, n_times) float32, volts
sfreq: float
channels: List[str]
bit_volts: List[float]
stream_id: str
def load_openephys_binary(
recording_dir: str,
*,
stream_substr: str = "AP",
) -> OpenEphysLoad:
"""Read Open Ephys binary-format recording (0.6+).
Parameters
----------
recording_dir : str
Path to `experimentX/recordingY/` containing `structure.oebin`.
stream_substr : str
Substring matched against `continuous[i].folder_name` to pick
the stream (e.g., "AP" for Neuropixels AP band).
Returns
-------
OpenEphysLoad
"""
rec_p = Path(recording_dir)
oebin = json.loads((rec_p / "structure.oebin").read_text(encoding="utf-8"))
stream = next(
(c for c in oebin["continuous"] if stream_substr in c["folder_name"]),
oebin["continuous"][0],
)
stream_dir = rec_p / "continuous" / stream["folder_name"]
n_ch = int(stream["num_channels"])
sfreq = float(stream["sample_rate"])
bit_volts = [float(ch["bit_volts"]) for ch in stream["channels"]]
channels = [ch["channel_name"] for ch in stream["channels"]]
dat_p = stream_dir / "continuous.dat"
n_total = dat_p.stat().st_size // (n_ch * 2)
raw = np.memmap(dat_p, dtype=np.int16, mode="r", shape=(n_total, n_ch))
arr = np.asarray(raw, dtype=np.float32).T # (n_ch, n_t)
# int16 → volts (assume "uV" units → multiply then ÷ 1e6 to land in V)
conv = np.asarray(bit_volts, dtype=np.float32)[:, None] / 1e6
arr = arr * conv
return OpenEphysLoad(
data=arr, sfreq=sfreq, channels=channels,
bit_volts=bit_volts, stream_id=stream["folder_name"],
)
from typing import Any, Dict
def operator_load_openephys(
data_dict: Dict[str, Any],
*,
path: str,
stream_substr: str = "AP",
) -> Dict[str, Any]:
"""EasyBCI-adapted Open Ephys binary-format loader.
Parameters
----------
data_dict : dict
OperatorIO (typically empty on first load).
path : str
Path to `experimentX/recordingY/` directory.
stream_substr : str
Stream selector; matches against `folder_name` (default "AP").
Returns
-------
dict
OperatorIO with `data`/`channels`/`frequency`/`duration` populated.
Raises
------
EasyBCIOperatorError
``recoverable=False`` on missing `structure.oebin` / corrupt manifest.
Modality coverage
-----------------
Spike (AP, sfreq >= 20 kHz): yes. LFP (LF, ~2.5 kHz): yes. ECoG (Intan): yes.
References
----------
Siegle et al. 2017 (Open Ephys); GUI v0.6 binary format docs.
Notes
-----
L0 IO operator; reads from disk (CODE_STANDARD Rule 12 exempt).
"""
import time
# easybci-allow: file-io # L0 IO operator; reading .dat is the function.
from easybci_lib.tools.neural_processing.operator_errors import EasyBCIOperatorError
if not path:
raise EasyBCIOperatorError(
operator="load_openephys", reason="path is required", recoverable=False
)
t0 = time.monotonic()
try:
load = load_openephys_binary(path, stream_substr=stream_substr)
except Exception as exc:
raise EasyBCIOperatorError(
operator="load_openephys", reason=f"load failed: {exc}", recoverable=False
) from exc
elapsed = time.monotonic() - t0
sfreq = load.sfreq
n_t = load.data.shape[1]
duration = n_t / sfreq
if sfreq >= 20_000:
modality = "spike"
elif sfreq >= 1500:
modality = "lfp"
else:
modality = "ecog"
return {
"data": load.data,
"channels": load.channels,
"frequency": sfreq,
"duration": duration,
"elapsed_s": elapsed,
"meta": {
"modality": modality,
"stream_id": load.stream_id,
"bit_volts": load.bit_volts,
"load_openephys": {"path": path, "stream_substr": stream_substr},
},
}
read_openephys reader.| Related format | When to prefer |
|---|---|
spikeglx | Use SpikeGLX when the acquisition rig is the IMEC-recommended SpikeGLX software stack. Open Ephys is the alternative open-source stack — both can drive Neuropixels but via different software. |
nwb | Use NWB when reading archived / published data (Open Ephys recordings published to DANDI are converted to NWB; the working format on the rig was Open Ephys). |
blackrock | Blackrock is the clinical UEA acquisition format; Open Ephys is open-source research. Mutually exclusive in practice. |