bidsreader 0.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (33) hide show
  1. bidsreader-0.1.0/.github/workflows/publish.yml +34 -0
  2. bidsreader-0.1.0/.github/workflows/test.yml +21 -0
  3. bidsreader-0.1.0/.gitignore +9 -0
  4. bidsreader-0.1.0/LICENSE +21 -0
  5. bidsreader-0.1.0/PKG-INFO +494 -0
  6. bidsreader-0.1.0/README.md +461 -0
  7. bidsreader-0.1.0/bidsreader/__init__.py +15 -0
  8. bidsreader-0.1.0/bidsreader/_errorwrap.py +50 -0
  9. bidsreader-0.1.0/bidsreader/basereader.py +208 -0
  10. bidsreader-0.1.0/bidsreader/cmlbidsreader.py +269 -0
  11. bidsreader-0.1.0/bidsreader/convert.py +57 -0
  12. bidsreader-0.1.0/bidsreader/exc.py +23 -0
  13. bidsreader-0.1.0/bidsreader/filtering.py +178 -0
  14. bidsreader-0.1.0/bidsreader/helpers.py +148 -0
  15. bidsreader-0.1.0/bidsreader/units.py +287 -0
  16. bidsreader-0.1.0/bidsreader.egg-info/PKG-INFO +494 -0
  17. bidsreader-0.1.0/bidsreader.egg-info/SOURCES.txt +31 -0
  18. bidsreader-0.1.0/bidsreader.egg-info/dependency_links.txt +1 -0
  19. bidsreader-0.1.0/bidsreader.egg-info/requires.txt +14 -0
  20. bidsreader-0.1.0/bidsreader.egg-info/top_level.txt +1 -0
  21. bidsreader-0.1.0/pyproject.toml +50 -0
  22. bidsreader-0.1.0/setup.cfg +4 -0
  23. bidsreader-0.1.0/tests/__init__.py +0 -0
  24. bidsreader-0.1.0/tests/conftest.py +86 -0
  25. bidsreader-0.1.0/tests/test_basereader.py +295 -0
  26. bidsreader-0.1.0/tests/test_cmlbidsreader.py +369 -0
  27. bidsreader-0.1.0/tests/test_convert.py +85 -0
  28. bidsreader-0.1.0/tests/test_errorwrap.py +106 -0
  29. bidsreader-0.1.0/tests/test_exc.py +78 -0
  30. bidsreader-0.1.0/tests/test_filtering.py +114 -0
  31. bidsreader-0.1.0/tests/test_helpers.py +251 -0
  32. bidsreader-0.1.0/tests/test_units.py +600 -0
  33. bidsreader-0.1.0/tutorials/bidsreader_tutorial.ipynb +960 -0
@@ -0,0 +1,34 @@
1
+ name: Publish to PyPI
2
+
3
+ on:
4
+ push:
5
+ tags:
6
+ - "v*"
7
+
8
+ jobs:
9
+ build:
10
+ runs-on: ubuntu-latest
11
+ steps:
12
+ - uses: actions/checkout@v4
13
+ - uses: actions/setup-python@v5
14
+ with:
15
+ python-version: "3.12"
16
+ - run: pip install build
17
+ - run: python -m build
18
+ - uses: actions/upload-artifact@v4
19
+ with:
20
+ name: dist
21
+ path: dist/
22
+
23
+ publish:
24
+ needs: build
25
+ runs-on: ubuntu-latest
26
+ environment: pypi
27
+ permissions:
28
+ id-token: write
29
+ steps:
30
+ - uses: actions/download-artifact@v4
31
+ with:
32
+ name: dist
33
+ path: dist/
34
+ - uses: pypa/gh-action-pypi-publish@release/v1
@@ -0,0 +1,21 @@
1
+ name: Tests
2
+
3
+ on:
4
+ push:
5
+ branches: [main]
6
+ pull_request:
7
+ branches: [main]
8
+
9
+ jobs:
10
+ test:
11
+ runs-on: ubuntu-latest
12
+ strategy:
13
+ matrix:
14
+ python-version: ["3.10", "3.11", "3.12"]
15
+ steps:
16
+ - uses: actions/checkout@v4
17
+ - uses: actions/setup-python@v5
18
+ with:
19
+ python-version: ${{ matrix.python-version }}
20
+ - run: pip install -e ".[dev]"
21
+ - run: pytest tests/ -v --tb=short
@@ -0,0 +1,9 @@
1
+ __pycache__/
2
+ *.pyc
3
+ .claude/
4
+ .ipynb_checkpoints/
5
+ *.egg-info/
6
+ .pytest_cache/
7
+ dist/
8
+ build/
9
+ .DS_Store
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2024-2026 Computational Memory Lab, University of Pennsylvania
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,494 @@
1
+ Metadata-Version: 2.4
2
+ Name: bidsreader
3
+ Version: 0.1.0
4
+ Summary: Data loader and file reader for the OpenBIDS format
5
+ Author: Computational Memory Lab
6
+ License-Expression: MIT
7
+ Project-URL: Homepage, https://github.com/pennmem/bidsreader
8
+ Project-URL: Repository, https://github.com/pennmem/bidsreader
9
+ Project-URL: Issues, https://github.com/pennmem/bidsreader/issues
10
+ Keywords: bids,eeg,ieeg,neuroscience,mne
11
+ Classifier: Development Status :: 3 - Alpha
12
+ Classifier: Intended Audience :: Science/Research
13
+ Classifier: Topic :: Scientific/Engineering :: Medical Science Apps.
14
+ Classifier: Programming Language :: Python :: 3
15
+ Classifier: Programming Language :: Python :: 3.10
16
+ Classifier: Programming Language :: Python :: 3.11
17
+ Classifier: Programming Language :: Python :: 3.12
18
+ Requires-Python: >=3.10
19
+ Description-Content-Type: text/markdown
20
+ License-File: LICENSE
21
+ Requires-Dist: mne>=1.0
22
+ Requires-Dist: mne-bids>=0.14
23
+ Requires-Dist: numpy>=1.23
24
+ Requires-Dist: pandas>=1.5
25
+ Provides-Extra: ptsa
26
+ Requires-Dist: ptsa; extra == "ptsa"
27
+ Provides-Extra: dev
28
+ Requires-Dist: pytest>=7.0; extra == "dev"
29
+ Requires-Dist: pytest-cov; extra == "dev"
30
+ Provides-Extra: all
31
+ Requires-Dist: bidsreader[dev,ptsa]; extra == "all"
32
+ Dynamic: license-file
33
+
34
+ # bidsreader
35
+
36
+ A Python library for reading and working with neuroimaging data stored in the [BIDS (Brain Imaging Data Structure)](https://bids.neuroimaging.io/) format. Provides a structured, object-oriented interface for loading EEG and iEEG data, events, electrodes, and channel metadata, with built-in support for MNE-Python and PTSA.
37
+
38
+ ## Features
39
+
40
+ - Load BIDS-compliant EEG/iEEG datasets with minimal boilerplate
41
+ - Automatic detection of device type (EEG vs iEEG) and coordinate space
42
+ - Load events, electrodes, channels, raw data, and epochs through a unified reader API
43
+ - Filter trials by type across events DataFrames, MNE Raw, and MNE Epochs
44
+ - Convert between MNE and PTSA data formats
45
+ - Detect and convert EEG signal units (V, mV, uV, nV, etc.)
46
+ - Custom exception hierarchy for clear, actionable error messages
47
+
48
+ ## Installation
49
+
50
+ ### Prerequisites
51
+
52
+ - Python 3.10+
53
+ - Access to a BIDS-formatted dataset
54
+
55
+ ### Install from source
56
+
57
+ ```bash
58
+ git clone <repository-url>
59
+ cd bidsreader
60
+ pip install -e .
61
+ ```
62
+
63
+ > **Note:** The project currently has no `pyproject.toml` or `setup.py`. To use it without one, add the project root to your Python path or install in development mode after creating a minimal `pyproject.toml` (see [Development Setup](#development-setup)).
64
+
65
+ ### Dependencies
66
+
67
+ **Required:**
68
+
69
+ | Package | Purpose |
70
+ |------------|----------------------------------|
71
+ | mne | EEG data structures and I/O |
72
+ | mne-bids | BIDS path resolution and reading |
73
+ | pandas | Tabular data (events, channels) |
74
+ | numpy | Numeric operations |
75
+
76
+ **Optional:**
77
+
78
+ | Package | Purpose |
79
+ |---------|------------------------------------------|
80
+ | ptsa | PTSA TimeSeries conversion (`convert_unit`, `mne_*_to_ptsa`) |
81
+ | pytest | Running the test suite |
82
+
83
+ Install all dependencies:
84
+
85
+ ```bash
86
+ pip install mne mne-bids pandas numpy
87
+ # Optional
88
+ pip install ptsa pytest
89
+ ```
90
+
91
+ ## Quick Start
92
+
93
+ *See a more robust tutorial in tutorials/*
94
+
95
+ ### Basic usage with CMLBIDSReader
96
+
97
+ ```python
98
+ from bidsreader import CMLBIDSReader
99
+
100
+ # Initialize a reader (defaults to /data/LTP_BIDS for CML data)
101
+ reader = CMLBIDSReader(subject="R1001P", task="FR1", session=0)
102
+
103
+ # Load behavioral events
104
+ events = reader.load_events("beh")
105
+
106
+ # Load electrode locations
107
+ electrodes = reader.load_electrodes()
108
+
109
+ # Load channel metadata (intracranial requires acquisition type)
110
+ channels = reader.load_channels("monopolar")
111
+
112
+ # Load combined channel + electrode data
113
+ combined = reader.load_combined_channels("bipolar")
114
+
115
+ # Load raw EEG data (returns MNE Raw object)
116
+ raw = reader.load_raw(acquisition="monopolar")
117
+
118
+ # Load epochs around events
119
+ epochs = reader.load_epochs(tmin=-0.5, tmax=1.5, acquisition="monopolar")
120
+ ```
121
+
122
+ ### Using a custom BIDS root
123
+
124
+ ```python
125
+ reader = CMLBIDSReader(
126
+ root="/path/to/your/bids/dataset",
127
+ subject="sub01",
128
+ task="rest",
129
+ session="01",
130
+ device="eeg",
131
+ )
132
+ ```
133
+
134
+ ### Querying dataset metadata
135
+
136
+ ```python
137
+ reader = CMLBIDSReader(root="/data/LTP_BIDS", subject="R1001P", task="FR1")
138
+
139
+ # List all subjects in the dataset
140
+ subjects = reader.get_dataset_subjects()
141
+
142
+ # List all tasks in the dataset
143
+ tasks = reader.get_dataset_tasks()
144
+
145
+ # List sessions for this subject
146
+ sessions = reader.get_subject_sessions()
147
+
148
+ # List tasks for this subject
149
+ subject_tasks = reader.get_subject_tasks()
150
+
151
+ # Get the highest session number across all subjects
152
+ max_session = reader.get_dataset_max_sessions(outlier_thresh=100)
153
+ ```
154
+
155
+ ### Changing reader fields after creation
156
+
157
+ ```python
158
+ reader = CMLBIDSReader(subject="R1001P", task="FR1", session=0)
159
+
160
+ # Switch to a different session
161
+ reader.set_fields(session=1)
162
+
163
+ # Switch subject and task
164
+ reader.set_fields(subject="R1002P", task="catFR1")
165
+ ```
166
+
167
+ ### Filtering events by trial type
168
+
169
+ ```python
170
+ from bidsreader import filter_events_df_by_trial_types, filter_by_trial_types
171
+
172
+ # Filter a DataFrame
173
+ events = reader.load_events("beh")
174
+ word_events, indices = filter_events_df_by_trial_types(events, ["WORD"])
175
+
176
+ # Filter across multiple data objects at once (with consistency checks)
177
+ filtered_df, filtered_raw_events, filtered_epochs, event_id, idx = filter_by_trial_types(
178
+ ["WORD", "STIM"],
179
+ events_df=events,
180
+ epochs=epochs,
181
+ )
182
+ ```
183
+
184
+ ### Unit detection and conversion
185
+
186
+ ```python
187
+ from bidsreader import detect_unit, get_scale_factor, convert_unit
188
+
189
+ # Detect the unit of an MNE object
190
+ unit = detect_unit(raw) # e.g., "V"
191
+
192
+ # Get conversion factor
193
+ factor = get_scale_factor("V", "uV") # 1_000_000.0
194
+
195
+ # Convert data to a target unit (returns a copy by default)
196
+ raw_uv = convert_unit(raw, "uV")
197
+ ```
198
+
199
+ ### Converting MNE data to PTSA TimeSeries
200
+
201
+ ```python
202
+ from bidsreader import mne_epochs_to_ptsa, mne_raw_to_ptsa
203
+
204
+ # Convert epochs (requires events DataFrame with 'sample' column)
205
+ ts = mne_epochs_to_ptsa(epochs, events)
206
+
207
+ # Convert raw data (optionally select channels and time window)
208
+ ts = mne_raw_to_ptsa(raw, picks=["E1", "E2"], tmin=0.0, tmax=10.0)
209
+ ```
210
+
211
+ ## Architecture
212
+
213
+ ### Class hierarchy
214
+
215
+ ```
216
+ BaseReader # Abstract base — BIDS path construction, metadata queries, field validation
217
+ └── CMLBIDSReader # Concrete reader for the CML (Computational Memory Lab) dataset
218
+ ```
219
+
220
+ ### Module overview
221
+
222
+ | Module | Purpose |
223
+ |------------------|----------------------------------------------------------|
224
+ | `basereader.py` | `BaseReader` class — shared BIDS logic and metadata queries |
225
+ | `cmlbidsreader.py` | `CMLBIDSReader` — CML-specific loading and auto-detection |
226
+ | `filtering.py` | Trial-type filtering for DataFrames, MNE Raw, and Epochs |
227
+ | `convert.py` | MNE to PTSA TimeSeries conversion |
228
+ | `units.py` | Unit detection, scaling, and conversion |
229
+ | `helpers.py` | Utility functions (validation, BIDS prefix handling, bipolar electrode merging) |
230
+ | `exc.py` | Custom exception hierarchy |
231
+ | `_errorwrap.py` | `@public_api` decorator for consistent exception wrapping |
232
+
233
+ ### Exception hierarchy
234
+
235
+ All exceptions inherit from `BIDSReaderError`, so you can catch everything with a single handler:
236
+
237
+ ```
238
+ BIDSReaderError
239
+ ├── InvalidOptionError # Invalid argument value
240
+ ├── MissingRequiredFieldError # Required reader field not set
241
+ ├── FileNotFoundBIDSError # Expected BIDS file not found
242
+ ├── AmbiguousMatchError # Multiple files matched when one expected
243
+ ├── DataParseError # TSV/JSON parsing failure
244
+ ├── DependencyError # Optional dependency issue
245
+ └── ExternalLibraryError # Unexpected error from MNE/pandas/etc.
246
+ ```
247
+
248
+ ```python
249
+ from bidsreader.exc import BIDSReaderError, FileNotFoundBIDSError
250
+
251
+ try:
252
+ events = reader.load_events()
253
+ except FileNotFoundBIDSError:
254
+ print("Events file not found for this subject/session")
255
+ except BIDSReaderError as e:
256
+ print(f"Something went wrong: {e}")
257
+ ```
258
+
259
+ ## Creating a New Reader
260
+
261
+ To support a different BIDS dataset, subclass `BaseReader` and implement your dataset-specific logic. Here is a step-by-step guide.
262
+
263
+ ### Step 1: Create your reader class
264
+
265
+ Create a new file (e.g., `bidsreader/myreader.py`):
266
+
267
+ ```python
268
+ import pandas as pd
269
+ import mne
270
+ from pathlib import Path
271
+ from typing import Optional, Union
272
+ from .basereader import BaseReader
273
+ from ._errorwrap import public_api
274
+ from .helpers import validate_option
275
+ from .exc import FileNotFoundBIDSError
276
+
277
+
278
+ class MyDatasetReader(BaseReader):
279
+ """Reader for the My Dataset BIDS archive."""
280
+
281
+ # Valid options for constrained fields
282
+ VALID_DEVICES = ("eeg", "meg")
283
+
284
+ def __init__(
285
+ self,
286
+ root: Optional[Union[str, Path]] = "/data/my_dataset",
287
+ subject: Optional[str] = None,
288
+ task: Optional[str] = None,
289
+ session: Optional[str | int] = None,
290
+ space: Optional[str] = None,
291
+ acquisition: Optional[str] = None,
292
+ device: Optional[str] = None,
293
+ ):
294
+ # Validate device before passing to base
295
+ device = validate_option("device", device, self.VALID_DEVICES)
296
+ super().__init__(
297
+ root=root,
298
+ subject=subject,
299
+ task=task,
300
+ session=session,
301
+ space=space,
302
+ acquisition=acquisition,
303
+ device=device,
304
+ )
305
+
306
+ # --- Override auto-detection hooks ---
307
+
308
+ def _determine_device(self) -> Optional[str]:
309
+ """Infer device type from subject ID or dataset structure.
310
+
311
+ Return None if it cannot be determined.
312
+ """
313
+ if self.subject is None:
314
+ return None
315
+ # Example: subjects starting with "MEG" use MEG
316
+ if self.subject.startswith("MEG"):
317
+ return "meg"
318
+ return "eeg"
319
+
320
+ def _determine_space(self) -> Optional[str]:
321
+ """Infer coordinate space from files on disk.
322
+
323
+ Return None or raise FileNotFoundBIDSError / AmbiguousMatchError
324
+ if it cannot be determined.
325
+ """
326
+ # Implement dataset-specific logic here
327
+ return "MNI152NLin2009aSym"
328
+
329
+ # --- Add your loading methods ---
330
+
331
+ @public_api
332
+ def load_events(self) -> pd.DataFrame:
333
+ """Load behavioral events for the current subject/session/task."""
334
+ self._require(("subject", "task", "session", "device"), context="load_events")
335
+
336
+ bp = self._bp(datatype="beh", suffix="beh", extension=".tsv")
337
+ matches = bp.match()
338
+ if not matches:
339
+ raise FileNotFoundBIDSError(f"No events file found for {bp}")
340
+
341
+ return pd.read_csv(matches[0].fpath, sep="\t")
342
+
343
+ @public_api
344
+ def load_raw(self) -> mne.io.BaseRaw:
345
+ """Load raw continuous data."""
346
+ from mne_bids import read_raw_bids
347
+
348
+ self._require(("subject", "task", "session", "device"), context="load_raw")
349
+ bp = self._bp(datatype=self.device)
350
+ return read_raw_bids(bp)
351
+ ```
352
+
353
+ ### Step 2: Key patterns to follow
354
+
355
+ 1. **Validate constrained fields in `__init__`** using `validate_option()` before calling `super().__init__()`.
356
+
357
+ 2. **Override `_determine_device()` and `_determine_space()`** to enable automatic detection. These are called lazily the first time `reader.device` or `reader.space` is accessed. Return `None` if detection fails — the base class will emit a warning.
358
+
359
+ 3. **Use `self._require(fields, context=...)`** at the start of each loading method to ensure the necessary fields are set before attempting file I/O.
360
+
361
+ 4. **Use `self._bp(**kwargs)`** to construct `BIDSPath` objects for file matching. This handles BIDS-standard path construction using the reader's current field values.
362
+
363
+ 5. **Decorate all public methods with `@public_api`** so that external exceptions (FileNotFoundError, JSONDecodeError, etc.) are automatically mapped to the `BIDSReaderError` hierarchy.
364
+
365
+ 6. **Use `self._add_bids_prefix(field, value)`** when you need to manually construct BIDS-prefixed path segments (e.g., `"sub-001"`, `"ses-0"`).
366
+
367
+ ### Step 3: Export your reader
368
+
369
+ Add your reader to [\_\_init\_\_.py](bidsreader/__init__.py):
370
+
371
+ ```python
372
+ from .myreader import MyDatasetReader
373
+ ```
374
+
375
+ ### Step 4: Write tests
376
+
377
+ Follow the patterns in [tests/conftest.py](tests/conftest.py) for fixtures and [tests/test_cmlbidsreader.py](tests/test_cmlbidsreader.py) for test structure. Key patterns:
378
+
379
+ - Use `tmp_path` fixtures to create temporary BIDS directory structures
380
+ - Use skip decorators for integration tests that require real data on disk
381
+ - Test both the happy path and error cases (missing fields, invalid options, missing files)
382
+
383
+ ```python
384
+ import pytest
385
+ from bidsreader import MyDatasetReader
386
+
387
+ @pytest.fixture
388
+ def my_reader(tmp_path):
389
+ return MyDatasetReader(root=tmp_path, subject="EEG001", task="rest", session=1)
390
+
391
+ def test_device_detection(my_reader):
392
+ assert my_reader.device == "eeg"
393
+
394
+ def test_missing_field_raises(tmp_path):
395
+ reader = MyDatasetReader(root=tmp_path, subject="EEG001", task="rest")
396
+ reader.session = None
397
+ with pytest.raises(Exception):
398
+ reader.load_events()
399
+ ```
400
+
401
+ ## Development Setup
402
+
403
+ ### Running tests
404
+
405
+ ```bash
406
+ # Run all tests
407
+ python -m pytest tests/
408
+
409
+ # Run a specific test file
410
+ python -m pytest tests/test_basereader.py -v
411
+
412
+ # Run with output
413
+ python -m pytest tests/ -v -s
414
+ ```
415
+
416
+ Integration tests that depend on real data at `/data/LTP_BIDS/` are skipped automatically when that data is not available.
417
+
418
+ ### Creating a pyproject.toml (recommended)
419
+
420
+ If you want proper `pip install -e .` support, create a `pyproject.toml`:
421
+
422
+ ```toml
423
+ [build-system]
424
+ requires = ["setuptools>=64"]
425
+ build-backend = "setuptools.backends._legacy:_Backend"
426
+
427
+ [project]
428
+ name = "bidsreader"
429
+ version = "0.1.0"
430
+ description = "Data loader and file reader for the OpenBIDS format"
431
+ requires-python = ">=3.10"
432
+ dependencies = [
433
+ "mne",
434
+ "mne-bids",
435
+ "pandas",
436
+ "numpy",
437
+ ]
438
+
439
+ [project.optional-dependencies]
440
+ ptsa = ["ptsa"]
441
+ dev = ["pytest"]
442
+ ```
443
+
444
+ Then install with:
445
+
446
+ ```bash
447
+ pip install -e ".[dev]"
448
+ ```
449
+
450
+ ## API Reference
451
+
452
+ ### BaseReader
453
+
454
+ | Method | Description |
455
+ |--------|-------------|
456
+ | `set_fields(**kwargs)` | Set multiple reader fields at once (chainable) |
457
+ | `get_dataset_subjects()` | List all subjects in the dataset |
458
+ | `get_dataset_tasks()` | List all tasks in the dataset |
459
+ | `get_subject_sessions()` | List sessions for the current subject |
460
+ | `get_subject_tasks()` | List tasks for the current subject |
461
+ | `get_dataset_max_sessions(outlier_thresh=None)` | Get highest session number across all subjects |
462
+
463
+ ### CMLBIDSReader
464
+
465
+ Inherits all `BaseReader` methods, plus:
466
+
467
+ | Method | Description |
468
+ |--------|-------------|
469
+ | `is_intracranial()` | Returns `True` if device is `"ieeg"` |
470
+ | `load_events(event_type="beh")` | Load events TSV (`"beh"` or device-type events) |
471
+ | `load_electrodes()` | Load electrode coordinates TSV |
472
+ | `load_channels(acquisition=None)` | Load channel metadata TSV (iEEG requires `"monopolar"` or `"bipolar"`) |
473
+ | `load_combined_channels(acquisition=None)` | Merge channel + electrode data into one DataFrame |
474
+ | `load_coordsystem_desc()` | Load coordinate system JSON metadata |
475
+ | `load_raw(acquisition=None)` | Load raw continuous data (returns `mne.io.BaseRaw`) |
476
+ | `load_epochs(tmin, tmax, events=None, baseline=None, acquisition=None, event_repeated="merge", channels=None, preload=False)` | Create `mne.Epochs` from raw data and events |
477
+
478
+ ### Standalone Functions
479
+
480
+ | Function | Module | Description |
481
+ |----------|--------|-------------|
482
+ | `filter_events_df_by_trial_types(events_df, trial_types)` | `filtering` | Filter events DataFrame by trial type |
483
+ | `filter_raw_events_by_trial_types(raw, trial_types)` | `filtering` | Filter MNE Raw annotations by trial type |
484
+ | `filter_epochs_by_trial_types(epochs, trial_types)` | `filtering` | Filter MNE Epochs by trial type |
485
+ | `filter_by_trial_types(trial_types, *, events_df, raw, epochs)` | `filtering` | Filter multiple data objects with consistency checks |
486
+ | `detect_unit(data, current_unit=None)` | `units` | Detect or validate EEG data unit |
487
+ | `get_scale_factor(from_unit, to_unit)` | `units` | Get multiplicative conversion factor between units |
488
+ | `convert_unit(data, target, *, current_unit=None, copy=True)` | `units` | Convert EEG data to a target unit |
489
+ | `mne_epochs_to_ptsa(epochs, events)` | `convert` | Convert MNE Epochs to PTSA TimeSeries |
490
+ | `mne_raw_to_ptsa(raw, picks=None, tmin=None, tmax=None)` | `convert` | Convert MNE Raw to PTSA TimeSeries |
491
+
492
+ ## License
493
+
494
+ TBD