Python API reference¶
Auto-generated from the source docstrings. For a task-oriented walkthrough see the Python guide.
The native API:
mef3io.Reader ¶
Reader(path: str, password: str = '', backend: str = 'cpp', n_threads: int = 0, cache=None)
Read-only interface to a MEF 3.0 session.
Times throughout are uUTC (microseconds since the Unix epoch). Windowed reads fetch only the bytes they need, so they stay cheap on huge sessions.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
path
|
str
|
Path to the |
required |
password
|
str
|
Password for encrypted sessions. A level-2 password unlocks everything; a level-1 password reads the signal and technical metadata but leaves subject metadata locked. Empty for unencrypted sessions. |
''
|
backend
|
('cpp', 'pure')
|
Which implementation to use. Defaults to the C++ backend; the pure backend is not yet implemented. |
"cpp"
|
n_threads
|
int
|
Worker threads for RED block decoding. |
0
|
cache
|
str or None
|
Opt-in warm-start cache for channel metadata. |
None
|
Examples:
>>> with mef3io.Reader("session.mefd") as r:
... x = r.read(r.channels[0], t0, t1) # float64, NaN in gaps
channels
property
¶
channels: list[str]
Channel names in the session, sorted.
Returns:
| Type | Description |
|---|---|
list of str
|
|
metadata
property
¶
metadata
Session subject/acquisition metadata as a :class:mef3io.Metadata.
Built from the first channel (metadata is session-wide). Subject fields are empty unless the reader was opened with a level-2 password.
Returns:
| Type | Description |
|---|---|
Metadata
|
|
close ¶
close() -> None
Release the backend. Optional (cleanup is automatic); present for API parity and context-manager use.
info ¶
info(channel: str) -> dict
Channel metadata.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
channel
|
str
|
Channel name. |
required |
Returns:
| Type | Description |
|---|---|
dict
|
Keys: |
read ¶
read(channel: str, t0: Optional[int] = None, t1: Optional[int] = None, n_threads: Optional[int] = None) -> np.ndarray
Read float64 samples on the uniform sampling grid.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
channel
|
str
|
Channel name. |
required |
t0
|
int or float
|
Half-open time window |
None
|
t1
|
int or float
|
Half-open time window |
None
|
n_threads
|
int
|
Per-call override of the reader's thread count ( |
None
|
Returns:
| Type | Description |
|---|---|
ndarray
|
1-D float64 array on the sampling grid. Discontinuity gaps are
filled with |
See Also
read_raw : the unscaled int32 form with an explicit validity mask.
read_raw ¶
read_raw(channel: str, t0: Optional[int] = None, t1: Optional[int] = None, n_threads: Optional[int] = None) -> dict
Read the stored int32 counts with an explicit validity mask.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
channel
|
str
|
Channel name. |
required |
t0
|
int or float
|
Half-open |
None
|
t1
|
int or float
|
Half-open |
None
|
n_threads
|
int
|
Per-call thread-count override (see :meth: |
None
|
Returns:
| Type | Description |
|---|---|
dict
|
Keys: |
segments ¶
segments(channel: str) -> list[dict]
Per-segment map of a channel — what data is where.
Read from metadata only (nothing is decoded), so it is cheap even for
huge, gap-riddled sessions. Use it to locate data across large
recording gaps, then :meth:toc for the block-level view within a
segment.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
channel
|
str
|
Channel name. |
required |
Returns:
| Type | Description |
|---|---|
list of dict
|
One dict per segment (sorted by segment number) with keys
|
toc ¶
toc(channel: str) -> list[dict]
Block-level table of contents, for seeking and viewers.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
channel
|
str
|
Channel name. |
required |
Returns:
| Type | Description |
|---|---|
list of dict
|
One dict per RED block with |
records ¶
records(channel: Optional[str] = None) -> list[dict]
Read records (annotations).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
channel
|
str or None
|
Channel name for channel-level records, or |
None
|
Returns:
| Type | Description |
|---|---|
list of dict
|
One dict per record with |
mef3io.Writer ¶
Writer(path: str, overwrite: bool = False, password1: str = '', password2: str = '', units: Optional[str] = None, block_length: Optional[int] = None, n_threads: int = 0, metadata=None)
Write a MEF 3.0 session.
Times throughout are uUTC (microseconds since the Unix epoch). The
first write to a channel creates segment 0; later writes append in-segment
(extending the existing files) unless new_segment=True.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
path
|
str
|
Path to the |
required |
overwrite
|
bool
|
|
False
|
password1
|
str
|
Level-1 and level-2 passwords. MEF has no "level-1 only" files, so to encrypt a session pass both; leave both empty for no encryption. |
''
|
password2
|
str
|
Level-1 and level-2 passwords. MEF has no "level-1 only" files, so to encrypt a session pass both; leave both empty for no encryption. |
''
|
units
|
str or None
|
Physical units label stored in metadata (e.g. |
None
|
block_length
|
int or None
|
RED block size in samples. |
None
|
n_threads
|
int
|
Worker threads for RED encoding ( |
0
|
metadata
|
Metadata or dict
|
Session-wide subject/acquisition metadata written to every channel.
Also settable later via :meth: |
None
|
Examples:
>>> with mef3io.Writer("session.mefd", overwrite=True, units="uV") as w:
... w.write("ch1", data, start_uutc, fs=256.0) # NaN marks gaps
set_metadata ¶
set_metadata(metadata) -> None
Set session-wide subject/acquisition metadata (a
:class:mef3io.Metadata, or a flat dict of fields). Call before
writing; applies to every channel.
close ¶
close() -> None
Finalize and release the writer. Called automatically on context-manager exit.
write ¶
write(channel: str, data: ndarray, start_uutc: int, fs: float, precision: int = -1, new_segment: bool = False) -> dict
Write float data; NaN runs become discontinuity gaps.
Values are quantized to int32 counts as round(data * 10**precision)
with the conversion factor 10**-precision kept in metadata. NaN
samples are not stored — they read back as NaN.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
channel
|
str
|
Channel name (created on first write). |
required |
data
|
array_like
|
Any numeric input; coerced to float64 (lists, int arrays,
|
required |
start_uutc
|
int or float
|
Timestamp of the first sample, uUTC. |
required |
fs
|
float
|
Sampling frequency in Hz. |
required |
precision
|
int
|
Decimal precision for quantization. |
-1
|
new_segment
|
bool
|
Force a fresh segment instead of appending in-segment. |
False
|
Returns:
| Type | Description |
|---|---|
dict
|
|
Raises:
| Type | Description |
|---|---|
RuntimeError
|
On an append conflict (fs / conversion-factor mismatch, or data starting before the segment's end). |
write_int32 ¶
write_int32(channel: str, data: ndarray, ufact: float, start_uutc: int, fs: float, valid: Optional[ndarray] = None, new_segment: bool = False) -> dict
Write integer counts verbatim with a conversion factor (bit-exact).
The primitive path: counts are stored exactly as given, with ufact
(e.g. an amplifier's volts-per-bit) in metadata. Physical units on read
are counts * ufact.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
channel
|
str
|
Channel name (created on first write). |
required |
data
|
array_like of int
|
Integer counts (any integer width). Stored bit-exact. |
required |
ufact
|
float
|
Conversion factor from counts to physical units. |
required |
start_uutc
|
int or float
|
Timestamp of the first sample, uUTC. |
required |
fs
|
float
|
Sampling frequency in Hz. |
required |
valid
|
array_like or None
|
Same length as |
None
|
new_segment
|
bool
|
Force a fresh segment instead of appending in-segment. |
False
|
Returns:
| Type | Description |
|---|---|
dict
|
|
Raises:
| Type | Description |
|---|---|
TypeError
|
If |
ValueError
|
If any value is outside the int32 range (it would wrap). |
RuntimeError
|
On an append conflict. |
write_annotations ¶
write_annotations(annotations, channel: Optional[str] = None) -> None
Write records (annotations).
Replaces the records at the given level. In encrypted sessions record bodies are level-2 encrypted.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
annotations
|
iterable of dict or pandas.DataFrame
|
Each record needs |
required |
channel
|
str or None
|
Channel name for channel-level records, or |
None
|
mef3io.archive_session ¶
archive_session(session_path, tar_path: Optional[str] = None, overwrite: bool = False) -> str
Pack a session directory into a single uncompressed tar archive.
The archive (conventionally name.mefd.tar) is a plain ustar file:
:class:Reader opens it directly — no extraction — and any tar tool
(tar -xf) reproduces the original directory. Because it is
uncompressed, windowed reads still fetch only the byte ranges they need.
The source directory is left untouched; output is deterministic, so
archiving the same session twice yields identical bytes. Tar sessions are
read-only: :class:Writer refuses .tar paths.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
session_path
|
str or path - like
|
The |
required |
tar_path
|
str
|
Target archive path; must end |
None
|
overwrite
|
bool
|
Replace an existing target archive. Default |
False
|
Returns:
| Type | Description |
|---|---|
str
|
Path of the created archive. |
Examples:
>>> tar = mef3io.archive_session("session.mefd")
>>> with mef3io.Reader(tar) as r:
... x = r.read(r.channels[0])
mef3io.extract_session ¶
extract_session(tar_path, dest_dir: Optional[str] = None, overwrite: bool = False) -> str
Unpack a session archive back into a .mefd directory.
The inverse of :func:archive_session — after extraction the directory is
a normal writable session again. The session root inside the archive is
stripped, so dest_dir becomes the session directory itself; archives
from foreign tar tools work too. A failed extraction never leaves a
half-written directory behind.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
tar_path
|
str or path - like
|
The session archive to unpack; must end |
required |
dest_dir
|
str
|
Target directory; must end |
None
|
overwrite
|
bool
|
Replace an existing target directory. Default |
False
|
Returns:
| Type | Description |
|---|---|
str
|
Path of the extracted session directory. |
Examples:
>>> session = mef3io.extract_session("session.mefd.tar")
>>> with mef3io.Writer(session) as w: # writable again
... w.write("ch1", more_data, t, fs=256.0)
Metadata objects¶
mef3io.Metadata
dataclass
¶
Metadata(subject: Subject = Subject(), acquisition: Acquisition = Acquisition())
Session-wide metadata: a :class:Subject and an :class:Acquisition
block. Written to every channel; on read, reflects the first channel.
mef3io.Subject
dataclass
¶
Subject(name_1: str = '', name_2: str = '', id: str = '', recording_location: str = '', gmt_offset: int = 0)
Subject / recording-context metadata (MEF section 3, level-2 encrypted).
mef3io.Acquisition
dataclass
¶
Acquisition(session_description: str = '', channel_description: str = '', reference_description: str = '', acquisition_channel_number: int = 1, low_frequency_filter: float = _UNSET_HZ, high_frequency_filter: float = _UNSET_HZ, notch_filter: float = _UNSET_HZ, line_frequency: float = _UNSET_HZ)
Descriptive / acquisition metadata (MEF section 2, level-1 encrypted).
Filter settings default to -1.0 meaning "not recorded".
Legacy mef_tools compatibility¶
Drop-in replacements for mef_tools.io — from mef3io import MefReader,
MefWriter. Same call shapes and defaults as the legacy classes; see the
legacy comparison for the measured differences.
mef3io.compat.MefReader ¶
MefReader(session_path: str, password2: Optional[str] = None)
mef_tools.io.MefReader-compatible reader.
session_path may also be an uncompressed tar archive of a session
(name.mefd.tar, see :func:mef3io.archive_session).
mef3io.compat.MefWriter ¶
MefWriter(session_path, overwrite=False, password1=None, password2=None, verbose=False, metadata=None)
mef_tools.io.MefWriter-compatible writer.
Like the legacy writer, appends extend the channel's last segment in place
(in-segment append); pass new_segment=True to start a fresh segment.
Metadata works two ways: mutate the legacy section3_dict /
section2_ts_dict (e.g. w.section3_dict['subject_ID'] = 'Smith') as
with mef_tools, or use the modern object via set_metadata / the
metadata= argument (mef3io.Metadata).
mef_block_len
property
writable
¶
mef_block_len
RED block length in samples (None = derive from fs, like legacy).
max_nans_written
property
writable
¶
max_nans_written: int
Kept for legacy compatibility. mef3io always splits data on NaN runs (never stores NaN as values), i.e. it behaves like the legacy writer's recommended setting of 0; other values are accepted and ignored.
record_offset
property
writable
¶
record_offset: int
Kept for legacy compatibility. mef3io writes records with a zero recording-time offset (annotation times round-trip unchanged either way); non-zero values are accepted and ignored.
set_metadata ¶
set_metadata(metadata) -> None
Set session-wide subject/acquisition metadata (a
:class:mef3io.Metadata or a flat dict). Applied on the next write.
get_mefblock_len ¶
get_mefblock_len(fs: float) -> int
Block length that will be used for data at fs (legacy formula).