{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "\n\n# Configuring MNE-Python\n\nThis tutorial covers how to configure MNE-Python to suit your local system and\nyour analysis preferences.\n\nWe begin by importing the necessary Python modules:\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "# Authors: The MNE-Python contributors.\n# License: BSD-3-Clause\n# Copyright the MNE-Python contributors." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "import os\n\nimport mne" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "\n## Getting and setting configuration variables\n\nConfiguration variables are read and written using the functions\n:func:`mne.get_config` and :func:`mne.set_config`. To read a specific\nconfiguration variable, pass its name to :func:`~mne.get_config` as the\n``key`` parameter (``key`` is the first parameter so you can pass it unnamed\nif you want):\n\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "print(mne.get_config(\"MNE_USE_CUDA\"))\nprint(type(mne.get_config(\"MNE_USE_CUDA\")))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Note that the string values read from the JSON file are not parsed in any\nway, so :func:`~mne.get_config` returns a string even for true/false config\nvalues, rather than a Python `boolean `.\nSimilarly, :func:`~mne.set_config` will only set string values (or ``None``\nvalues, to unset a variable):\n\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "try:\n mne.set_config(\"MNE_USE_CUDA\", True)\nexcept TypeError as err:\n print(err)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "If you're unsure whether a config variable has been set, there is a\nconvenient way to check it and provide a fallback in case it doesn't exist:\n:func:`~mne.get_config` has a ``default`` parameter.\n\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "print(mne.get_config(\"missing_config_key\", default=\"fallback value\"))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "There are also two convenience modes of :func:`~mne.get_config`. The first\nwill return a :class:`dict` containing all config variables (and their\nvalues) that have been set on your system; this is done by passing\n``key=None`` (which is the default, so it can be omitted):\n\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "print(mne.get_config()) # same as mne.get_config(key=None)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The second convenience mode will return a :class:`tuple` of all the keys that\nMNE-Python recognizes and uses, regardless of whether they've been set on\nyour system. This is done by passing an empty string ``''`` as the ``key``:\n\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "print(mne.get_config(key=\"\"))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "It is possible to add config variables that are not part of the recognized\nlist, by passing any arbitrary key to :func:`~mne.set_config`. This will\nyield a warning, however, which is a nice check in cases where you meant to\nset a valid key but simply misspelled it:\n\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "mne.set_config(\"MNEE_USE_CUUDAA\", \"false\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Let's delete that config variable we just created. To unset a config\nvariable, use :func:`~mne.set_config` with ``value=None``. Since we're still\ndealing with an unrecognized key (as far as MNE-Python is concerned) we'll\nstill get a warning, but the key will be unset:\n\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "mne.set_config(\"MNEE_USE_CUUDAA\", None)\nassert \"MNEE_USE_CUUDAA\" not in mne.get_config(\"\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Where configurations are stored\n\nMNE-Python stores configuration variables in a `JSON`_ file. By default, this\nfile is located in :file:`{%USERPROFILE%}\\\\.mne\\\\mne-python.json` on Windows\nand :file:`{$HOME}/.mne/mne-python.json` on Linux or macOS. You can get the\nfull path to the config file with :func:`mne.get_config_path`.\n\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "print(mne.get_config_path())" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "However it is not a good idea to directly edit files in the :file:`.mne`\ndirectory; use the getting and setting functions described in `the\nprevious section `.\n\nIf for some reason you want to load the configuration from a different\nlocation, you can pass the ``home_dir`` parameter to\n:func:`~mne.get_config_path`, specifying the parent directory of the\n:file:`.mne` directory where the configuration file you wish to load is\nstored.\n\n\n## Using environment variables\n\nFor compatibility with :doc:`MNE-C <../../install/mne_c>`, MNE-Python\nalso reads and writes `environment variables`_ to specify configuration. This\nis done with the same functions that read and write the JSON configuration,\nand is controlled with the parameters ``use_env`` and ``set_env``. By\ndefault, :func:`~mne.get_config` will check :data:`os.environ` before\nchecking the MNE-Python JSON file; to check *only* the JSON file use\n``use_env=False``. To demonstrate, here's an environment variable that is not\nspecific to MNE-Python (and thus is not in the JSON config file):\n\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "# make sure it's not in the JSON file (no error means our assertion held):\nassert mne.get_config(\"PATH\", use_env=False) is None\n# but it *is* in the environment:\nprint(mne.get_config(\"PATH\"))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Also by default, :func:`~mne.set_config` will set values in both the JSON\nfile and in :data:`os.environ`; to set a config variable *only* in the JSON\nfile use ``set_env=False``. Here we'll use :func:`print` statement to confirm\nthat an environment variable is being created and deleted (we could have used\nthe Python `assert statement ` instead, but it doesn't print any\noutput when it succeeds so it's a little less obvious):\n\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "mne.set_config(\"foo\", \"bar\", set_env=False)\nprint(\"foo\" in os.environ.keys())\nmne.set_config(\"foo\", \"bar\")\nprint(\"foo\" in os.environ.keys())\nmne.set_config(\"foo\", None) # unsetting a key deletes var from environment\nprint(\"foo\" in os.environ.keys())" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "\n## Logging\n\nOne important configuration variable is ``MNE_LOGGING_LEVEL``. Throughout the\nmodule, messages are generated describing the actions MNE-Python is taking\nbehind-the-scenes. How you set ``MNE_LOGGING_LEVEL`` determines how many of\nthose messages you see. The default logging level on a fresh install of\nMNE-Python is ``info``:\n\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "print(mne.get_config(\"MNE_LOGGING_LEVEL\"))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The logging levels that can be set as config variables are ``debug``,\n``info``, ``warning``, ``error``, and ``critical``. Around 90% of the log\nmessages in MNE-Python are ``info`` messages, so for most users the choice is\nbetween ``info`` (tell me what is happening) and ``warning`` (tell me only if\nsomething worrisome happens). The ``debug`` logging level is intended for\nMNE-Python developers.\n\n\nIn `an earlier section ` we saw how\n:func:`mne.set_config` is used to change the logging level for the current\nPython session and all future sessions. To change the logging level only for\nthe current Python session, you can use :func:`mne.set_log_level` instead.\nThe :func:`~mne.set_log_level` function takes the same five string options\nthat are used for the ``MNE_LOGGING_LEVEL`` config variable; additionally, it\ncan accept :class:`int` or :class:`bool` values that are equivalent to those\nstrings. The equivalencies are given in this table:\n\n\n+----------+---------+---------+\n| String | Integer | Boolean |\n+==========+=========+=========+\n| DEBUG | 10 | |\n+----------+---------+---------+\n| INFO | 20 | True |\n+----------+---------+---------+\n| WARNING | 30 | False |\n+----------+---------+---------+\n| ERROR | 40 | |\n+----------+---------+---------+\n| CRITICAL | 50 | |\n+----------+---------+---------+\n\nWith many MNE-Python functions it is possible to change the logging level\ntemporarily for just that function call, by using the ``verbose`` parameter.\nTo illustrate this, we'll load some sample data with different logging levels\nset. First, with log level ``warning``:\n\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "kit_data_path = os.path.join(\n os.path.abspath(os.path.dirname(mne.__file__)),\n \"io\",\n \"kit\",\n \"tests\",\n \"data\",\n \"test.sqd\",\n)\nraw = mne.io.read_raw_kit(kit_data_path, verbose=\"warning\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "No messages were generated, because none of the messages were of severity\n\"warning\" or worse. Next, we'll load the same file with log level ``info``\n(the default level):\n\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "raw = mne.io.read_raw_kit(kit_data_path, verbose=\"info\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "This time, we got a few messages about extracting information from the file,\nconverting that information into the MNE-Python :class:`~mne.Info` format,\netc. Finally, if we request ``debug``-level information, we get even more\ndetail -- and we do so this time using the :func:`mne.use_log_level` context\nmanager, which is another way to accomplish the same thing as passing\n``verbose='debug'``:\n\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "with mne.use_log_level(\"debug\"):\n raw = mne.io.read_raw_kit(kit_data_path)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We've been passing string values to the ``verbose`` parameter, but we can see\nfrom `the table above ` that ``verbose=True`` will\ngive us the ``info`` messages and ``verbose=False`` will suppress them; this\nis a useful shorthand to use in scripts, so you don't have to remember the\nspecific names of the different logging levels. One final note:\n``verbose=None`` (which is the default for functions that have a ``verbose``\nparameter) will fall back on whatever logging level was most recently set by\n:func:`mne.set_log_level`, or if that hasn't been called during the current\nPython session, it will fall back to the value of\n``mne.get_config('MNE_LOGGING_LEVEL')``.\n\n## Getting information about your system\nYou can also get information about what ``mne`` imports as dependencies from\nyour system. This can be done via the command line with:\n\n```console\n$ mne sys_info\n```\nOr you can use :func:`mne.sys_info` directly, which prints to ``stdout`` by\ndefault:\n\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "mne.sys_info()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ ".. LINKS\n\n\n" ] } ], "metadata": { "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.12.2" } }, "nbformat": 4, "nbformat_minor": 0 }