Skip to content

Commit

Permalink
Merge remote-tracking branch 'upstream/main' into info
Browse files Browse the repository at this point in the history
* upstream/main:
  ENH: Change known_config_types to dict (mne-tools#11166)
  MAINT: Improve README (mne-tools#11673)
  • Loading branch information
larsoner committed May 4, 2023
2 parents 9a14e80 + da3823f commit 1ae6fa3
Show file tree
Hide file tree
Showing 7 changed files with 166 additions and 100 deletions.
21 changes: 10 additions & 11 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -39,14 +39,22 @@ Documentation
`MNE documentation`_ for MNE-Python is available online.


Forum
^^^^^^

Our user forum is https://mne.discourse.group and is the best place to ask
questions about MNE-Python usage or about the contribution process. It also
includes job opportunities and other announcements.


Installing MNE-Python
^^^^^^^^^^^^^^^^^^^^^

To install the latest stable version of MNE-Python, you can use pip_ in a terminal:

.. code-block:: console
$ pip install -U mne
$ pip install --upgrade mne
- MNE-Python 0.17 was the last release to support Python 2.7
- MNE-Python 0.18 requires Python 3.5 or higher
Expand All @@ -65,17 +73,14 @@ To install the latest version of the code using pip_ open a terminal and type:

.. code-block:: console
$ pip install -U https://github.com/mne-tools/mne-python/archive/main.zip
$ pip install --upgrade git+https://github.com/mne-tools/mne-python@main
To get the latest code using `git <https://git-scm.com/>`__, open a terminal and type:

.. code-block:: console
$ git clone https://github.com/mne-tools/mne-python.git
Alternatively, you can also download a
`zip file of the latest development version <https://github.com/mne-tools/mne-python/archive/main.zip>`__.

Dependencies
^^^^^^^^^^^^
Expand Down Expand Up @@ -126,12 +131,6 @@ Please see the documentation on the MNE-Python homepage:
https://mne.tools/dev/install/contributing.html


Forum
^^^^^^

https://mne.discourse.group


Licensing
^^^^^^^^^

Expand Down
1 change: 1 addition & 0 deletions doc/changes/latest.inc
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ Enhancements
- Added ability to read stimulus durations from SNIRF files when using :func:`mne.io.read_raw_snirf` (:gh:`11397` by `Robert Luke`_)
- Add :meth:`mne.Info.save` to save an :class:`mne.Info` object to a fif file (:gh:`11401` by `Alex Rockhill`_)
- Improved error message when downloads are corrupted for :func:`mne.datasets.sample.data_path` and related functions (:gh:`11407` by `Eric Larson`_)
- Improved :func:`mne.get_config("") <mne.get_config>` behavior to return a dict of key-value pairs (config key and its description) rather than just a tuple of config keys (:gh:`11166` by `Clemens Brunner`_, `Daniel McCloy`_, and `Eric Larson`_)
- Add support for ``skip_by_annotation`` in :func:`mne.io.Raw.notch_filter` (:gh:`11388` by `Mainak Jas`_)
- Add support for ``output='complex'`` to :func:`mne.time_frequency.psd_array_welch` and when using ``method='welch'`` with :meth:`mne.Epochs.compute_psd` (:gh:`11556` by `Eric Larson`_)
- Slightly adjusted the window title for :func:`mne.Epochs.plot` (:gh:`11419` by `Richard Höchenberger`_ and `Daniel McCloy`_)
Expand Down
1 change: 1 addition & 0 deletions doc/logging.rst
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ Logging and Configuration
set_log_file
set_config
set_cache_dir
set_memmap_min_size
sys_info
use_log_level
verbose
Expand Down
2 changes: 1 addition & 1 deletion mne/parallel.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ def parallel_func(
triggers automated memory mapping. Can be an int in Bytes,
or a human-readable string, e.g., '1M' for 1 megabyte.
Use None to disable memmaping of large arrays. Use 'auto' to
use the value set using mne.set_memmap_min_size.
use the value set using :func:`mne.set_memmap_min_size`.
pre_dispatch : int | str
See :class:`joblib.Parallel`.
total : int | None
Expand Down
224 changes: 140 additions & 84 deletions mne/utils/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,98 +56,152 @@ def set_memmap_min_size(memmap_min_size):
mapping for parallel processing, e.g., '1M' for 1 megabyte.
Use None to disable memmaping of large arrays.
"""
_validate_type(memmap_min_size, (str, None), "memmap_min_size")
if memmap_min_size is not None:
if not isinstance(memmap_min_size, str):
raise ValueError("'memmap_min_size' has to be a string.")
if memmap_min_size[-1] not in ["K", "M", "G"]:
raise ValueError(
"The size has to be given in kilo-, mega-, or "
"gigabytes, e.g., 100K, 500M, 1G."
f"gigabytes, e.g., 100K, 500M, 1G, got {repr(memmap_min_size)}"
)

set_config("MNE_MEMMAP_MIN_SIZE", memmap_min_size, set_env=False)


# List the known configuration values
known_config_types = (
"MNE_3D_OPTION_ANTIALIAS",
"MNE_3D_OPTION_DEPTH_PEELING",
"MNE_3D_OPTION_MULTI_SAMPLES",
"MNE_3D_OPTION_SMOOTH_SHADING",
"MNE_3D_OPTION_THEME",
"MNE_BROWSE_RAW_SIZE",
"MNE_BROWSER_BACKEND",
"MNE_BROWSER_OVERVIEW_MODE",
"MNE_BROWSER_PRECOMPUTE",
"MNE_BROWSER_THEME",
"MNE_BROWSER_USE_OPENGL",
"MNE_CACHE_DIR",
"MNE_COREG_ADVANCED_RENDERING",
"MNE_COREG_COPY_ANNOT",
"MNE_COREG_FULLSCREEN",
"MNE_COREG_GUESS_MRI_SUBJECT",
"MNE_COREG_HEAD_HIGH_RES",
"MNE_COREG_HEAD_OPACITY",
"MNE_COREG_HEAD_INSIDE",
"MNE_COREG_INTERACTION",
"MNE_COREG_MARK_INSIDE",
"MNE_COREG_PREPARE_BEM",
"MNE_COREG_ORIENT_TO_SURFACE",
"MNE_COREG_SCALE_LABELS",
"MNE_COREG_SCALE_BY_DISTANCE",
"MNE_COREG_SCENE_SCALE",
"MNE_COREG_WINDOW_HEIGHT",
"MNE_COREG_WINDOW_WIDTH",
"MNE_COREG_SUBJECTS_DIR",
"MNE_CUDA_DEVICE",
"MNE_CUDA_IGNORE_PRECISION",
"MNE_DATA",
"MNE_DATASETS_BRAINSTORM_PATH",
"MNE_DATASETS_EEGBCI_PATH",
"MNE_DATASETS_EPILEPSY_ECOG_PATH",
"MNE_DATASETS_EYELINK_PATH",
"MNE_DATASETS_HF_SEF_PATH",
"MNE_DATASETS_MEGSIM_PATH",
"MNE_DATASETS_MISC_PATH",
"MNE_DATASETS_MTRF_PATH",
"MNE_DATASETS_SAMPLE_PATH",
"MNE_DATASETS_SOMATO_PATH",
"MNE_DATASETS_MULTIMODAL_PATH",
"MNE_DATASETS_FNIRS_MOTOR_PATH",
"MNE_DATASETS_OPM_PATH",
"MNE_DATASETS_SPM_FACE_DATASETS_TESTS",
"MNE_DATASETS_SPM_FACE_PATH",
"MNE_DATASETS_TESTING_PATH",
"MNE_DATASETS_VISUAL_92_CATEGORIES_PATH",
"MNE_DATASETS_KILOWORD_PATH",
"MNE_DATASETS_FIELDTRIP_CMC_PATH",
"MNE_DATASETS_PHANTOM_4DBTI_PATH",
"MNE_DATASETS_LIMO_PATH",
"MNE_DATASETS_REFMEG_NOISE_PATH",
"MNE_DATASETS_SSVEP_PATH",
"MNE_DATASETS_ERP_CORE_PATH",
"MNE_DATASETS_EPILEPSY_ECOG_PATH",
"MNE_DATASETS_UCL_OPM_AUDITORY_PATH",
"MNE_FORCE_SERIAL",
"MNE_KIT2FIFF_STIM_CHANNELS",
"MNE_KIT2FIFF_STIM_CHANNEL_CODING",
"MNE_KIT2FIFF_STIM_CHANNEL_SLOPE",
"MNE_KIT2FIFF_STIM_CHANNEL_THRESHOLD",
"MNE_LOGGING_LEVEL",
"MNE_MEMMAP_MIN_SIZE",
"MNE_REPR_HTML",
"MNE_SKIP_FTP_TESTS",
"MNE_SKIP_NETWORK_TESTS",
"MNE_SKIP_TESTING_DATASET_TESTS",
"MNE_STIM_CHANNEL",
"MNE_TQDM",
"MNE_USE_CUDA",
"MNE_USE_NUMBA",
"SUBJECTS_DIR",
)
_known_config_types = {
"MNE_3D_OPTION_ANTIALIAS": (
"bool, whether to use full-screen antialiasing in 3D plots"
),
"MNE_3D_OPTION_DEPTH_PEELING": "bool, whether to use depth peeling in 3D plots",
"MNE_3D_OPTION_MULTI_SAMPLES": (
"int, number of samples to use for full-screen antialiasing"
),
"MNE_3D_OPTION_SMOOTH_SHADING": ("bool, whether to use smooth shading in 3D plots"),
"MNE_3D_OPTION_THEME": ("str, the color theme (light or dark) to use for 3D plots"),
"MNE_BROWSE_RAW_SIZE": (
"tuple, width and height of the raw browser window (in inches)"
),
"MNE_BROWSER_BACKEND": (
"str, the backend to use for the MNE Browse Raw window (qt or matplotlib)"
),
"MNE_BROWSER_OVERVIEW_MODE": (
"str, the overview mode to use in the MNE Browse Raw window )"
"(see mne.viz.plot_raw for valid options)"
),
"MNE_BROWSER_PRECOMPUTE": (
"bool, whether to precompute raw data in the MNE Browse Raw window"
),
"MNE_BROWSER_THEME": "str, the color theme (light or dark) to use for the browser",
"MNE_BROWSER_USE_OPENGL": (
"bool, whether to use OpenGL for rendering in the MNE Browse Raw window"
),
"MNE_CACHE_DIR": "str, path to the cache directory for parallel execution",
"MNE_COREG_ADVANCED_RENDERING": (
"bool, whether to use advanced OpenGL rendering in mne coreg"
),
"MNE_COREG_COPY_ANNOT": (
"bool, whether to copy the annotation files during warping"
),
"MNE_COREG_FULLSCREEN": "bool, whether to use full-screen mode in mne coreg",
"MNE_COREG_GUESS_MRI_SUBJECT": (
"bool, whether to guess the MRI subject in mne coreg"
),
"MNE_COREG_HEAD_HIGH_RES": (
"bool, whether to use high-res head surface in mne coreg"
),
"MNE_COREG_HEAD_OPACITY": ("bool, the head surface opacity to use in mne coreg"),
"MNE_COREG_HEAD_INSIDE": (
"bool, whether to add an opaque inner scalp head surface to help "
"occlude points behind the head in mne coreg"
),
"MNE_COREG_INTERACTION": (
"str, interaction style in mne coreg (trackball or terrain)"
),
"MNE_COREG_MARK_INSIDE": (
"bool, whether to mark points inside the head surface in mne coreg"
),
"MNE_COREG_PREPARE_BEM": (
"bool, whether to prepare the BEM solution after warping in mne coreg"
),
"MNE_COREG_ORIENT_TO_SURFACE": (
"bool, whether to orient the digitization markers to the head surface "
"in mne coreg"
),
"MNE_COREG_SCALE_LABELS": (
"bool, whether to scale the MRI labels during warping in mne coreg"
),
"MNE_COREG_SCALE_BY_DISTANCE": (
"bool, whether to scale the digitization markers by their distance from "
"the scalp in mne coreg"
),
"MNE_COREG_SCENE_SCALE": (
"float, the scale factor of the 3D scene in mne coreg (default 0.16)"
),
"MNE_COREG_WINDOW_HEIGHT": "int, window height for mne coreg",
"MNE_COREG_WINDOW_WIDTH": "int, window width for mne coreg",
"MNE_COREG_SUBJECTS_DIR": "str, path to the subjects directory for mne coreg",
"MNE_CUDA_DEVICE": "int, CUDA device to use for GPU processing",
"MNE_DATA": "str, default data directory",
"MNE_DATASETS_BRAINSTORM_PATH": "str, path for brainstorm data",
"MNE_DATASETS_EEGBCI_PATH": "str, path for EEGBCI data",
"MNE_DATASETS_EPILEPSY_ECOG_PATH": "str, path for epilepsy_ecog data",
"MNE_DATASETS_HF_SEF_PATH": "str, path for HF_SEF data",
"MNE_DATASETS_MEGSIM_PATH": "str, path for MEGSIM data",
"MNE_DATASETS_MISC_PATH": "str, path for misc data",
"MNE_DATASETS_MTRF_PATH": "str, path for MTRF data",
"MNE_DATASETS_SAMPLE_PATH": "str, path for sample data",
"MNE_DATASETS_SOMATO_PATH": "str, path for somato data",
"MNE_DATASETS_MULTIMODAL_PATH": "str, path for multimodal data",
"MNE_DATASETS_FNIRS_MOTOR_PATH": "str, path for fnirs_motor data",
"MNE_DATASETS_OPM_PATH": "str, path for OPM data",
"MNE_DATASETS_SPM_FACE_DATASETS_TESTS": "str, path for spm_face data",
"MNE_DATASETS_SPM_FACE_PATH": "str, path for spm_face data",
"MNE_DATASETS_TESTING_PATH": "str, path for testing data",
"MNE_DATASETS_VISUAL_92_CATEGORIES_PATH": "str, path for visual_92_categories data",
"MNE_DATASETS_KILOWORD_PATH": "str, path for kiloword data",
"MNE_DATASETS_FIELDTRIP_CMC_PATH": "str, path for fieldtrip_cmc data",
"MNE_DATASETS_PHANTOM_4DBTI_PATH": "str, path for phantom_4dbti data",
"MNE_DATASETS_LIMO_PATH": "str, path for limo data",
"MNE_DATASETS_REFMEG_NOISE_PATH": "str, path for refmeg_noise data",
"MNE_DATASETS_SSVEP_PATH": "str, path for ssvep data",
"MNE_DATASETS_ERP_CORE_PATH": "str, path for erp_core data",
"MNE_FORCE_SERIAL": "bool, force serial rather than parallel execution",
"MNE_LOGGING_LEVEL": (
"str or int, controls the level of verbosity of any function "
"decorated with @verbose. See "
"https://mne.tools/stable/auto_tutorials/intro/50_configure_mne.html#logging"
),
"MNE_MEMMAP_MIN_SIZE": (
"str, threshold on the minimum size of arrays passed to the workers that "
"triggers automated memory mapping, e.g., 1M or 0.5G"
),
"MNE_REPR_HTML": (
"bool, represent some of our objects with rich HTML in a notebook "
"environment"
),
"MNE_SKIP_NETWORK_TESTS": (
"bool, used in a test decorator (@requires_good_network) to skip "
"tests that include large downloads"
),
"MNE_SKIP_TESTING_DATASET_TESTS": (
"bool, used in test decorators (@requires_spm_data, "
"@requires_bstraw_data) to skip tests that require specific datasets"
),
"MNE_STIM_CHANNEL": "string, the default channel name for mne.find_events",
"MNE_TQDM": (
'str, either "tqdm", "tqdm.auto", or "off". Controls presence/absence '
"of progress bars"
),
"MNE_USE_CUDA": "bool, use GPU for filtering/resampling",
"MNE_USE_NUMBA": (
"bool, use Numba just-in-time compiler for some of our intensive "
"computations"
),
"SUBJECTS_DIR": "path-like, directory of freesurfer MRI files for each subject",
}

# These allow for partial matches, e.g. 'MNE_STIM_CHANNEL_1' is okay key
known_config_wildcards = (
_known_config_wildcards = (
"MNE_STIM_CHANNEL",
"MNE_DATASETS_FNIRS",
"MNE_NIRS",
Expand Down Expand Up @@ -229,7 +283,9 @@ def get_config(key=None, default=None, raise_error=False, home_dir=None, use_env
_validate_type(key, (str, type(None)), "key", "string or None")

if key == "":
return known_config_types
# These are str->str (immutable) so we should just copy the dict
# itself, no need for deepcopy
return _known_config_types.copy()

# first, check to see if key is in env
if use_env and key is not None and key in os.environ:
Expand All @@ -245,7 +301,7 @@ def get_config(key=None, default=None, raise_error=False, home_dir=None, use_env
if key is None:
# update config with environment variables
if use_env:
env_keys = set(config).union(known_config_types).intersection(os.environ)
env_keys = set(config).union(_known_config_types).intersection(os.environ)
config.update({key: os.environ[key] for key in env_keys})
return config
elif raise_error is True and key not in config:
Expand Down Expand Up @@ -301,8 +357,8 @@ def set_config(key, value, home_dir=None, set_env=True):
if value is not None:
value = str(value)

if key not in known_config_types and not any(
key.startswith(k) for k in known_config_wildcards
if key not in _known_config_types and not any(
key.startswith(k) for k in _known_config_wildcards
):
warn('Setting non-standard config type: "%s"' % key)

Expand Down
10 changes: 8 additions & 2 deletions mne/utils/tests/test_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,12 @@ def test_config(tmp_path):
assert get_config(key) == value
del os.environ[key]
# catch the warning about it being a non-standard config key
assert len(get_config("")) > 10 # tuple of valid keys
known_config_keys = get_config("")
assert len(known_config_keys) > 10 # dict of valid keys
for k, val in known_config_keys.items():
assert isinstance(k, str)
assert isinstance(val, str), k
assert len(val) > 0, k
with pytest.warns(RuntimeWarning, match="non-standard"):
set_config(key, None, home_dir=tempdir, set_env=False)
assert get_config(key, home_dir=tempdir) is None
Expand Down Expand Up @@ -77,7 +82,8 @@ def test_config(tmp_path):
pytest.raises(RuntimeError, set_config, key, "true", home_dir=tempdir)

# degenerate conditions
pytest.raises(ValueError, set_memmap_min_size, 1)
with pytest.raises(TypeError, match="must be an instance"):
set_memmap_min_size(1)
pytest.raises(ValueError, set_memmap_min_size, "foo")
pytest.raises(TypeError, get_config, 1)
pytest.raises(TypeError, set_config, 1)
Expand Down
7 changes: 5 additions & 2 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -85,9 +85,12 @@ def package_tree(pkgroot):
],
keywords="neuroscience neuroimaging MEG EEG ECoG fNIRS brain",
project_urls={
"Homepage": "https://mne.tools/",
"Download": "https://pypi.org/project/scikit-learn/#files",
"Bug Tracker": "https://github.com/mne-tools/mne-python/issues/",
"Documentation": "https://mne.tools/",
"Source": "https://github.com/mne-tools/mne-python/",
"Tracker": "https://github.com/mne-tools/mne-python/issues/",
"Forum": "https://mne.discourse.group/",
"Source Code": "https://github.com/mne-tools/mne-python/",
},
platforms="any",
python_requires=">=3.8",
Expand Down

0 comments on commit 1ae6fa3

Please sign in to comment.