-
Notifications
You must be signed in to change notification settings - Fork 92
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[MRG] Add tiny BIDS test dataset, fix doctests, and run it in CI (#831)
* fix doctests in path.py * test: use pytest --doctest-modules * fix some more examples * make use of _write_json instead of json.dump * fix fine-calib and crosstalk doctest * DATA: add tiny_bids test dataset ~800kb * fix all doctests using new test ds * add code for generating tiny_bids * fix example, sphinx warning * use tiny_bids in bidspath example, fix #829 * write TSV files with newline character * add missing newlines at end of files * do not run pytest on examples we did not do that before either, but --doctest-modules is now ON and that option apparently also runs the examples * add whatsnew for TSV line end * properly ignore examples in pytest * fix head_to_mri upstream API change * xfail doctest on windows due to / vs \ * BIDSPath __str__ always .as_posix() * fix op.join -> Path * root in __repr__ --> posix path or None * circumvent bids_path.root __str__ * 1) fix pep, 2) fix type hints, 3) fix example ds * fix type hint * I should run make pep before pushing
- Loading branch information
1 parent
2d8a721
commit 0db039f
Showing
24 changed files
with
722 additions
and
100 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,9 @@ | ||
"""Inspect and annotate BIDS raw data.""" | ||
# Authors: Richard Höchenberger <[email protected]> | ||
# Stefan Appelhoff <[email protected]> | ||
# | ||
# License: BSD (3-clause) | ||
|
||
from pathlib import Path | ||
|
||
import numpy as np | ||
|
@@ -78,8 +84,12 @@ def inspect_dataset(bids_path, find_flat=True, l_freq=None, h_freq=None, | |
Disable flat channel & segment detection, and apply a filter with a | ||
passband of 1–30 Hz. | ||
>>> inspect_dataset(bids_path=bids_path, find_flat=False, | ||
l_freq=1, h_freq=30) | ||
>>> from mne_bids import BIDSPath | ||
>>> root = Path('./mne_bids/tests/data/tiny_bids').absolute() | ||
>>> bids_path = BIDSPath(subject='01', task='rest', session='eeg', | ||
... suffix='eeg', extension='.vhdr', root=root) | ||
>>> inspect_dataset(bids_path=bids_path, find_flat=False, # doctest: +SKIP | ||
... l_freq=1, h_freq=30) | ||
""" | ||
allowed_extensions = set(ALLOWED_DATATYPE_EXTENSIONS['meg'] + | ||
ALLOWED_DATATYPE_EXTENSIONS['eeg'] + | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,6 @@ | ||
"""BIDS compatible path functionality.""" | ||
# Authors: Adam Li <[email protected]> | ||
# Stefan Appelhoff <[email protected]> | ||
# | ||
# License: BSD (3-clause) | ||
import glob | ||
|
@@ -13,7 +14,7 @@ | |
from pathlib import Path | ||
from datetime import datetime | ||
import json | ||
from typing import Optional, Union | ||
from typing import Optional | ||
|
||
import numpy as np | ||
from mne.utils import warn, logger, _validate_type | ||
|
@@ -224,37 +225,50 @@ class BIDSPath(object): | |
Examples | ||
-------- | ||
Generate a BIDSPath object and inspect it | ||
>>> bids_path = BIDSPath(subject='test', session='two', task='mytask', | ||
suffix='ieeg', extension='.edf') | ||
... suffix='ieeg', extension='.edf') | ||
>>> print(bids_path.basename) | ||
sub-test_ses-two_task-mytask_ieeg.edf | ||
>>> bids_path | ||
BIDSPath(root: None, | ||
BIDSPath( | ||
root: None | ||
datatype: ieeg | ||
basename: sub-test_ses-two_task-mytask_ieeg.edf) | ||
>>> # copy and update multiple entities at once | ||
Copy and update multiple entities at once | ||
>>> new_bids_path = bids_path.copy().update(subject='test2', | ||
session='one') | ||
... session='one') | ||
>>> print(new_bids_path.basename) | ||
sub-test2_ses-one_task-mytask_ieeg.edf | ||
>>> # printing the BIDSPath will show relative path when | ||
>>> # root is not set | ||
Printing a BIDSPath will show a relative path when `root` is not set | ||
>>> print(new_bids_path) | ||
sub-test2/ses-one/ieeg/sub-test2_ses-one_task-mytask_ieeg.edf | ||
>>> new_bids_path.update(suffix='channels', extension='.tsv') | ||
>>> # setting suffix without an identifiable datatype will | ||
>>> # result in a wildcard at the datatype directory level | ||
Setting `suffix` without an identifiable datatype will make | ||
BIDSPath try to guess the datatype | ||
>>> new_bids_path = new_bids_path.update(suffix='channels', | ||
... extension='.tsv') | ||
>>> print(new_bids_path) | ||
sub-test2/ses-one/*/sub-test2_ses-one_task-mytask_channels.tsv | ||
>>> # set a root for the BIDS dataset | ||
>>> new_bids_path.update(root='/bids_dataset') | ||
>>> print(new_bids_path.root) | ||
sub-test2/ses-one/ieeg/sub-test2_ses-one_task-mytask_channels.tsv | ||
You can set a new root for the BIDS dataset. Let's see what the | ||
different properties look like for our object: | ||
>>> new_bids_path = new_bids_path.update(root='/bids_dataset') | ||
>>> print(new_bids_path.root.as_posix()) | ||
/bids_dataset | ||
>>> print(new_bids_path.basename) | ||
sub-test2_ses-one_task-mytask_ieeg.edf | ||
sub-test2_ses-one_task-mytask_channels.tsv | ||
>>> print(new_bids_path) | ||
/bids_dataset/sub-test2/ses-one/ieeg/sub-test2_ses-one_task-mytask_ieeg.edf | ||
>>> print(new_bids_path.directory) | ||
/bids_dataset/sub-test2/ses-one/ieeg/ | ||
/bids_dataset/sub-test2/ses-one/ieeg/sub-test2_ses-one_task-mytask_channels.tsv | ||
>>> print(new_bids_path.directory.as_posix()) | ||
/bids_dataset/sub-test2/ses-one/ieeg | ||
Notes | ||
----- | ||
|
@@ -440,7 +454,7 @@ def suffix(self, value): | |
self.update(suffix=value) | ||
|
||
@property | ||
def root(self) -> Optional[Union[str, Path]]: | ||
def root(self) -> Optional[Path]: | ||
"""The root directory of the BIDS dataset.""" | ||
return self._root | ||
|
||
|
@@ -477,12 +491,14 @@ def extension(self, value): | |
|
||
def __str__(self): | ||
"""Return the string representation of the path.""" | ||
return str(self.fpath) | ||
return str(self.fpath.as_posix()) | ||
|
||
def __repr__(self): | ||
"""Representation in the style of `pathlib.Path`.""" | ||
root = self.root.as_posix() if self.root is not None else None | ||
|
||
return f'{self.__class__.__name__}(\n' \ | ||
f'root: {self.root}\n' \ | ||
f'root: {root}\n' \ | ||
f'datatype: {self.datatype}\n' \ | ||
f'basename: {self.basename})' | ||
|
||
|
@@ -651,13 +667,13 @@ def update(self, *, check=None, **kwargs): | |
:func:`mne_bids.BIDSPath`: | ||
>>> bids_path = BIDSPath(subject='test', session='two', | ||
task='mytask', suffix='channels', | ||
extension='.tsv') | ||
... task='mytask', suffix='channels', | ||
... extension='.tsv') | ||
>>> print(bids_path.basename) | ||
sub-test_ses-two_task-mytask_channels.tsv | ||
>>> # Then, one can update this `BIDSPath` object in place | ||
>>> bids_path.update(acquisition='test', suffix='ieeg', | ||
extension='.vhdr', task=None) | ||
>>> bids_path = bids_path.update(acquisition='test', suffix='ieeg', | ||
... extension='.vhdr', task=None) | ||
>>> print(bids_path.basename) | ||
sub-test_ses-two_acq-test_ieeg.vhdr | ||
""" | ||
|
@@ -1147,16 +1163,16 @@ def get_entities_from_fname(fname, on_error='raise'): | |
-------- | ||
>>> fname = 'sub-01_ses-exp_run-02_meg.fif' | ||
>>> get_entities_from_fname(fname) | ||
{'subject': '01', | ||
'session': 'exp', | ||
'task': None, | ||
'acquisition': None, | ||
'run': '02', | ||
'processing': None, | ||
'space': None, | ||
'recording': None, | ||
'split': None, | ||
'suffix': 'meg'} | ||
{'subject': '01', \ | ||
'session': 'exp', \ | ||
'task': None, \ | ||
'acquisition': None, \ | ||
'run': '02', \ | ||
'processing': None, \ | ||
'space': None, \ | ||
'recording': None, \ | ||
'split': None, \ | ||
'suffix': 'meg'} | ||
""" | ||
if on_error not in ('warn', 'raise', 'ignore'): | ||
raise ValueError(f'Acceptable values for on_error are: warn, raise, ' | ||
|
@@ -1398,12 +1414,12 @@ def get_entity_vals(root, entity_key, *, ignore_subjects='emptyroom', | |
Examples | ||
-------- | ||
>>> root = os.path.expanduser('~/mne_data/eeg_matchingpennies') | ||
>>> root = Path('./mne_bids/tests/data/tiny_bids').absolute() | ||
>>> entity_key = 'subject' | ||
>>> get_entity_vals(root, entity_key) | ||
['05', '06', '07', '08', '09', '10', '11'] | ||
['01'] | ||
>>> get_entity_vals(root, entity_key, with_key=True) | ||
['sub-05', 'sub-06', 'sub-07', 'sub-08', 'sub-09', 'sub-10', 'sub-11'] | ||
['sub-01'] | ||
Notes | ||
----- | ||
|
Oops, something went wrong.