Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions doc/changes/devel/12771.apichange.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
:func:`mne.datasets.fetch_fsaverage` now returns a :class:`python:pathlib.Path` object
rather than a string. Support for string concatenation with plus (``+``) is thus
deprecated and will be removed in 1.9, use the forward-slash ``/`` operator instead,
by `Eric Larson`_.
14 changes: 6 additions & 8 deletions examples/inverse/morph_volume_stc.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,6 @@
# Copyright the MNE-Python contributors.

# %%
import os

import nibabel as nib
from nilearn.plotting import plot_glass_brain

Expand All @@ -40,15 +38,15 @@
# %%
# Setup paths
sample_dir_raw = sample.data_path()
sample_dir = os.path.join(sample_dir_raw, "MEG", "sample")
subjects_dir = os.path.join(sample_dir_raw, "subjects")
sample_dir = sample_dir_raw / "MEG" / "sample"
subjects_dir = sample_dir_raw / "subjects"

fname_evoked = os.path.join(sample_dir, "sample_audvis-ave.fif")
fname_inv = os.path.join(sample_dir, "sample_audvis-meg-vol-7-meg-inv.fif")
fname_evoked = sample_dir / "sample_audvis-ave.fif"
fname_inv = sample_dir / "sample_audvis-meg-vol-7-meg-inv.fif"

fname_t1_fsaverage = os.path.join(subjects_dir, "fsaverage", "mri", "brain.mgz")
fname_t1_fsaverage = subjects_dir / "fsaverage" / "mri" / "brain.mgz"
fetch_fsaverage(subjects_dir) # ensure fsaverage src exists
fname_src_fsaverage = subjects_dir + "/fsaverage/bem/fsaverage-vol-5-src.fif"
fname_src_fsaverage = subjects_dir / "fsaverage" / "bem" / "fsaverage-vol-5-src.fif"

# %%
# Compute example data. For reference see :ref:`ex-inverse-volume`.
Expand Down
97 changes: 49 additions & 48 deletions mne/datasets/_fsaverage/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,12 @@
# Copyright the MNE-Python contributors.

import os
import os.path as op
from pathlib import Path, PosixPath, WindowsPath

from ...utils import get_subjects_dir, set_config, verbose
from ...utils import get_subjects_dir, set_config, verbose, warn
from ..utils import _get_path, _manifest_check_download

FSAVERAGE_MANIFEST_PATH = op.dirname(__file__)
FSAVERAGE_MANIFEST_PATH = Path(__file__).parent


@verbose
Expand All @@ -26,9 +26,12 @@ def fetch_fsaverage(subjects_dir=None, *, verbose=None):

Returns
-------
fs_dir : str
fs_dir : Path
The fsaverage directory.
(essentially ``subjects_dir + '/fsaverage'``).
(essentially ``subjects_dir / 'fsaverage'``).

.. versionchanged:: 1.8
A :class:`pathlib.Path` object is returned instead of a string.

Notes
-----
Expand Down Expand Up @@ -65,69 +68,67 @@ def fetch_fsaverage(subjects_dir=None, *, verbose=None):
# fid.write('\n'.join(names))
#
subjects_dir = _set_montage_coreg_path(subjects_dir)
subjects_dir = op.abspath(op.expanduser(subjects_dir))
fs_dir = op.join(subjects_dir, "fsaverage")
os.makedirs(fs_dir, exist_ok=True)
subjects_dir = subjects_dir.expanduser().absolute()
fs_dir = subjects_dir / "fsaverage"
fs_dir.mkdir(parents=True, exist_ok=True)
_manifest_check_download(
manifest_path=op.join(FSAVERAGE_MANIFEST_PATH, "root.txt"),
destination=op.join(subjects_dir),
manifest_path=FSAVERAGE_MANIFEST_PATH / "root.txt",
destination=subjects_dir,
url="https://osf.io/3bxqt/download?version=2",
hash_="5133fe92b7b8f03ae19219d5f46e4177",
)
_manifest_check_download(
manifest_path=op.join(FSAVERAGE_MANIFEST_PATH, "bem.txt"),
destination=op.join(subjects_dir, "fsaverage"),
manifest_path=FSAVERAGE_MANIFEST_PATH / "bem.txt",
destination=subjects_dir / "fsaverage",
url="https://osf.io/7ve8g/download?version=4",
hash_="b31509cdcf7908af6a83dc5ee8f49fb1",
)
return fs_dir
return _mne_path(fs_dir)


def _get_create_subjects_dir(subjects_dir):
subjects_dir = get_subjects_dir(subjects_dir, raise_error=False)
if subjects_dir is None:
subjects_dir = _get_path(None, "MNE_DATA", "montage coregistration")
subjects_dir = op.join(subjects_dir, "MNE-fsaverage-data")
os.makedirs(subjects_dir, exist_ok=True)
else:
subjects_dir = str(subjects_dir)
subjects_dir = subjects_dir / "MNE-fsaverage-data"
subjects_dir.mkdir(parents=True, exist_ok=True)
return subjects_dir


def _set_montage_coreg_path(subjects_dir=None):
"""Set a subject directory suitable for montage(-only) coregistration.

Parameters
----------
subjects_dir : path-like | None
The path to use as the subjects directory in the MNE-Python
config file. None will use the existing config variable (i.e.,
will not change anything), and if it does not exist, will use
``~/mne_data/MNE-fsaverage-data``.

Returns
-------
subjects_dir : str
The subjects directory that was used.

See Also
--------
mne.datasets.fetch_fsaverage
mne.get_config
mne.set_config

Notes
-----
If you plan to only do EEG-montage based coregistrations with fsaverage
without any MRI warping, this function can facilitate the process.
Essentially it sets the default value for ``subjects_dir`` in MNE
functions to be ``~/mne_data/MNE-fsaverage-data`` (assuming it has
not already been set to some other value).

.. versionadded:: 0.18
"""
"""Set a subject directory suitable for montage(-only) coregistration."""
subjects_dir = _get_create_subjects_dir(subjects_dir)
old_subjects_dir = get_subjects_dir(None, raise_error=False)
if old_subjects_dir is None:
set_config("SUBJECTS_DIR", subjects_dir)
return subjects_dir


# Adapted from pathlib.Path.__new__
def _mne_path(path):
klass = MNEWindowsPath if os.name == "nt" else MNEPosixPath
out = klass(path)
assert isinstance(out, klass)
return out


class _PathAdd:
def __add__(self, other):
if isinstance(other, str):
warn(
"data_path functions now return pathlib.Path objects which "
"do not natively support the plus (+) operator, switch to "
"using forward slash (/) instead. Support for plus will be "
"removed in 1.2.",
FutureWarning,
)
return f"{str(self)}{other}"
raise NotImplementedError


class MNEWindowsPath(_PathAdd, WindowsPath): # noqa: D101
pass


class MNEPosixPath(_PathAdd, PosixPath): # noqa: D101
pass
13 changes: 6 additions & 7 deletions mne/datasets/_infant/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,7 @@
# License: BSD-3-Clause
# Copyright the MNE-Python contributors.

import os
import os.path as op
from pathlib import Path

from ...utils import _check_option, _validate_type, get_subjects_dir, verbose
from ..utils import _manifest_check_download
Expand All @@ -27,7 +26,7 @@
75fe37a1bc80ed6793a8abb47681d5ab ANTS7-5Months3T.zip
790f7dba0a264262e6c1c2dfdf216215 ANTS9-0Months3T.zip
"""
_MANIFEST_PATH = op.dirname(__file__)
_MANIFEST_PATH = Path(__file__).parent


@verbose
Expand Down Expand Up @@ -80,15 +79,15 @@ def fetch_infant_template(age, subjects_dir=None, *, verbose=None):
dash = "-5" if ".5" in age else "-0"
subject = f"ANTS{first}{dash}{unit}3T"
# Actually get and create the files
subj_dir = subjects_dir / subject
os.makedirs(subj_dir, exist_ok=True)
subject_dir = subjects_dir / subject
subject_dir.mkdir(parents=True, exist_ok=True)
# .zip -> hash mapping
orig_hashes = dict(
line.strip().split()[::-1] for line in _ORIGINAL_HASHES.strip().splitlines()
)
_manifest_check_download(
manifest_path=op.join(_MANIFEST_PATH, f"{subject}.txt"),
destination=subj_dir,
manifest_path=_MANIFEST_PATH / f"{subject}.txt",
destination=subject_dir,
url=_ORIGINAL_URL.format(subject=subject),
hash_=orig_hashes[f"{subject}.zip"],
)
Expand Down
11 changes: 5 additions & 6 deletions mne/datasets/_phantom/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,12 @@
# License: BSD-3-Clause
# Copyright the MNE-Python contributors.

import os
import os.path as op
from pathlib import Path

from ...utils import _check_option, _validate_type, get_subjects_dir, verbose
from ..utils import _manifest_check_download

PHANTOM_MANIFEST_PATH = op.dirname(__file__)
PHANTOM_MANIFEST_PATH = Path(__file__).parent


@verbose
Expand All @@ -24,7 +23,7 @@ def fetch_phantom(kind, subjects_dir=None, *, verbose=None):

Returns
-------
subject_dir : str
subject_dir : pathlib.Path
The resulting phantom subject directory.

See Also
Expand Down Expand Up @@ -54,9 +53,9 @@ def fetch_phantom(kind, subjects_dir=None, *, verbose=None):
subjects_dir = get_subjects_dir(subjects_dir, raise_error=True)
subject = f"phantom_{kind}"
subject_dir = subjects_dir / subject
os.makedirs(subject_dir, exist_ok=True)
subject_dir.mkdir(parents=True, exist_ok=True)
_manifest_check_download(
manifest_path=op.join(PHANTOM_MANIFEST_PATH, f"{subject}.txt"),
manifest_path=PHANTOM_MANIFEST_PATH / f"{subject}.txt",
destination=subjects_dir,
url=phantoms[kind]["url"],
hash_=phantoms[kind]["hash"],
Expand Down
Loading