Compare commits
31 Commits
master
...
maint/0.16
| Author | SHA1 | Date | |
|---|---|---|---|
| 508691405e | |||
| 56b5eaea82 | |||
| 7a098c9e10 | |||
| 50b2ed8eef | |||
| 5162e8df0f | |||
| 80d649ec5e | |||
| 5c3105ce3f | |||
| eacb0b75c5 | |||
| 62f95aa22d | |||
| 57c93296ec | |||
| ed9cf77e40 | |||
| f985d705f3 | |||
| 33a42d6e3c | |||
| 384ffac3cc | |||
| 2123efe335 | |||
| d4c562a5e2 | |||
| 3cfc4ecbcc | |||
| ffd431d669 | |||
| 5989b56c3c | |||
| c408f9b7c1 | |||
| 1d7fcc36dc | |||
| bb62c6b548 | |||
| 3362e69542 | |||
| f3e9fda794 | |||
| 29e40e578c | |||
| 7044aeb2f4 | |||
| c003bf663f | |||
| c919f8f1c0 | |||
| d52c574eab | |||
| e56da5d55d | |||
| 3fa2d36898 |
+47
-26
@@ -1,8 +1,11 @@
|
||||
# Tagging a commit with [circle front] will build the front page and perform test-doc.
|
||||
# Tagging a commit with [circle full] will build everything.
|
||||
version: 2
|
||||
jobs:
|
||||
build:
|
||||
docker:
|
||||
- image: circleci/python:3.6-stretch
|
||||
# 3.6-jessie is too new for conda
|
||||
- image: circleci/python:3.6-jessie
|
||||
steps:
|
||||
# Get our data and merge with upstream
|
||||
- checkout
|
||||
@@ -19,8 +22,17 @@ jobs:
|
||||
- restore_cache:
|
||||
keys:
|
||||
- data-cache
|
||||
- pip-cache
|
||||
|
||||
# Spin up Xvfb
|
||||
- run: /sbin/start-stop-daemon --start --quiet --pidfile /tmp/custom_xvfb_99.pid --make-pidfile --background --exec /usr/bin/Xvfb -- :99 -screen 0 1400x900x24 -ac +extension GLX +render -noreset;
|
||||
- run: echo "export DISPLAY=:99" >> $BASH_ENV;
|
||||
# Fix libgcc_s.so.1 pthread_cancel bug:
|
||||
# https://github.com/ContinuumIO/anaconda-issues/issues/9190#issuecomment-386508136
|
||||
# https://github.com/golemfactory/golem/issues/1019
|
||||
- run: sudo apt-get install libgl1-mesa-glx libegl1-mesa libxrandr2 libxrandr2 libxss1 libxcursor1 libxcomposite1 libasound2 libxi6 libxtst6 qt5-default
|
||||
# Get latest Anaconda running
|
||||
- run: sudo apt-get install libgl1-mesa-glx libegl1-mesa libxrandr2 libxrandr2 libxss1 libxcursor1 libxcomposite1 libasound2 libxi6 libxtst6
|
||||
- run: echo "export DISPLAY=:99" >> $BASH_ENV
|
||||
- run: echo "export PATH=~/miniconda/envs/mne/bin:~/miniconda/bin:$PATH" >> $BASH_ENV
|
||||
- run: /sbin/start-stop-daemon --start --quiet --pidfile /tmp/custom_xvfb_99.pid --make-pidfile --background --exec /usr/bin/Xvfb -- :99 -screen 0 1400x900x24 -ac +extension GLX +render -noreset;
|
||||
@@ -29,21 +41,31 @@ jobs:
|
||||
wget -q http://repo.continuum.io/miniconda/Miniconda-latest-Linux-x86_64.sh -O ~/miniconda.sh;
|
||||
chmod +x ~/miniconda.sh;
|
||||
~/miniconda.sh -b -p ~/miniconda;
|
||||
echo "export PATH=~/miniconda/bin:$PATH" >> $BASH_ENV;
|
||||
- run:
|
||||
command: |
|
||||
conda update --yes --quiet conda;
|
||||
conda env create --quiet -f environment.yml;
|
||||
source activate mne;
|
||||
pip uninstall --yes mne;
|
||||
# This is a CircleCI-specific fix -- for some reason 5.9.2 is problematic
|
||||
# here but not on Travis, we get:
|
||||
#
|
||||
# libgcc_s.so.1 must be installed for pthread_cancel to work
|
||||
# Aborted
|
||||
#
|
||||
- run: pip install --upgrade --no-deps pyqt5>=5.10
|
||||
echo "source activate mne" >> $BASH_ENV;
|
||||
- save_cache:
|
||||
key: pip-cache
|
||||
paths:
|
||||
- ~/.cache/pip
|
||||
# The conda-provided PyQt5 does not work on CircleCI for some reason,
|
||||
# possibly because the libGL expects a sufficiently modern libgcc
|
||||
# and conda rolls their own (libgcc-ng package).
|
||||
- run: conda remove --yes qt pyqt matplotlib sip libxcb icu vtk
|
||||
- run: pip uninstall --yes mayavi vtk
|
||||
- run: pip install vtk mayavi PyQt5 PyQt5-sip sip matplotlib
|
||||
- run: echo "export LD_PRELOAD=~/miniconda/envs/mne/lib/libgobject-2.0.so.0.5600.1" >> $BASH_ENV
|
||||
# Look at what we have and fail early if there is some library conflict
|
||||
- run: which python
|
||||
- run: python -c "import mne; mne.sys_info()"
|
||||
- run: python -c "from mayavi import mlab; import matplotlib.pyplot as plt; mlab.figure(); plt.figure()"
|
||||
- run: LIBGL_DEBUG=verbose python -c "from mayavi import mlab; import matplotlib.pyplot as plt; mlab.figure(); plt.figure()"
|
||||
- run: python -c "import mne; mne.set_config('MNE_LOGGING_LEVEL', 'info')"
|
||||
- run: python -c "import mne; level = mne.get_config('MNE_LOGGING_LEVEL'); assert level.lower() == 'info', repr(level)"
|
||||
|
||||
# Figure out if we should run a full, pattern, or noplot version
|
||||
- run: python setup.py develop
|
||||
@@ -53,17 +75,17 @@ jobs:
|
||||
- run: mkdir -p ~/mne_data
|
||||
- run:
|
||||
command: |
|
||||
if [[ $(cat gitlog.txt) == *"[circle front]"* ]]; then
|
||||
PATTERN="plot_mne_dspm_source_localization.py\|plot_receptive_field.py\|plot_mne_inverse_label_connectivity.py\|plot_sensors_decoding.py\|plot_stats_cluster_spatio_temporal.py\|plot_visualize_evoked.py\|";
|
||||
else
|
||||
PATTERN="";
|
||||
fi;
|
||||
touch pattern.txt;
|
||||
if [ "$CIRCLE_BRANCH" == "master" ] || [[ $(cat gitlog.txt) == *"[circle full]"* ]]; then
|
||||
echo html_dev > build.txt;
|
||||
elif [ "$CIRCLE_BRANCH" == "maint/0.16" ]; then
|
||||
echo html_stable > build.txt;
|
||||
else
|
||||
FNAMES=$(git diff --name-only $CIRCLE_BRANCH $(git merge-base $CIRCLE_BRANCH upstream/master));
|
||||
if [[ $(cat gitlog.txt) == *"[circle front]"* ]]; then
|
||||
FNAMES="tutorials/plot_mne_dspm_source_localization.py tutorials/plot_receptive_field.py examples/connectivity/plot_mne_inverse_label_connectivity.py tutorials/plot_sensors_decoding.py tutorials/plot_stats_cluster_spatio_temporal.py tutorials/plot_visualize_evoked.py "${FNAMES};
|
||||
python -c "import mne; print(mne.datasets.testing.data_path(update_path=True))";
|
||||
fi;
|
||||
echo FNAMES="$FNAMES";
|
||||
for FNAME in $FNAMES; do
|
||||
if [[ `expr match $FNAME "\(tutorials\|examples\)/.*plot_.*\.py"` ]] ; then
|
||||
@@ -128,7 +150,6 @@ jobs:
|
||||
fi;
|
||||
done;
|
||||
echo PATTERN="$PATTERN";
|
||||
echo NEED_SAMPLE="$NEED_SAMPLE";
|
||||
if [[ $PATTERN ]]; then
|
||||
PATTERN="\(${PATTERN::-2}\)";
|
||||
echo html_dev-pattern > build.txt;
|
||||
@@ -137,7 +158,8 @@ jobs:
|
||||
fi;
|
||||
fi;
|
||||
echo "$PATTERN" > pattern.txt;
|
||||
- run: echo BUILD="$(cat build.txt)"
|
||||
- run: echo "PATTERN=$(cat pattern.txt)"
|
||||
- run: echo "BUILD=$(cat build.txt)"
|
||||
- run: ls -al ~/mne_data;
|
||||
- run:
|
||||
command: |
|
||||
@@ -145,19 +167,18 @@ jobs:
|
||||
SUBJECTS_DIR=~/mne_data/MNE-sample-data/subjects python -c "import mne; mne.datasets._download_all_example_data()";
|
||||
fi;
|
||||
- run: if [ ! -d ~/mne-tools.github.io ]; then git clone https://github.com/mne-tools/mne-tools.github.io.git ~/mne-tools.github.io --depth=1; fi;
|
||||
# Run doctest (if it's full or front) before building the docs
|
||||
- run:
|
||||
command: |
|
||||
if [[ $(cat build.txt) == "html_dev-noplot" ]]; then
|
||||
cd doc;
|
||||
make html_dev-noplot;
|
||||
elif [[ $(cat build.txt) == "html_dev-pattern" ]]; then
|
||||
cd doc;
|
||||
PATTERN=$(cat ../pattern.txt) make html_dev-pattern;
|
||||
else
|
||||
if [[ $(cat gitlog.txt) == *"[circle front]"* ]] || [[ $(cat build.txt) == "html_dev" ]] || [[ $(cat build.txt) == "html_stable" ]]; then
|
||||
make test-doc;
|
||||
cd doc;
|
||||
make $(cat ../build.txt);
|
||||
fi;
|
||||
# Build docs
|
||||
- run:
|
||||
command: |
|
||||
cd doc;
|
||||
PATTERN=$(cat ../pattern.txt) make $(cat ../build.txt);
|
||||
- run: python -c "import mne; level = mne.get_config('MNE_LOGGING_LEVEL'); assert level.lower() == 'info', repr(level)"
|
||||
|
||||
- store_artifacts:
|
||||
path: doc/_build/html/
|
||||
@@ -200,7 +221,7 @@ jobs:
|
||||
git config --global user.email "circle@mne.com";
|
||||
git config --global user.name "Circle Ci";
|
||||
pushd ~/mne-tools.github.io && git checkout master && git pull origin master && popd;
|
||||
pushd doc/_build && rm -Rf ~/mne-tools.github.io/stable cp -a html_stable ~/mne-tools.github.io/stable && popd;
|
||||
pushd doc/_build && rm -Rf ~/mne-tools.github.io/stable && cp -a html_stable ~/mne-tools.github.io/stable && popd;
|
||||
pushd ~/mne-tools.github.io && git add -A && git commit -m "CircleCI update of stable docs (${CIRCLE_BUILD_NUM})." && git push origin master && popd;
|
||||
else
|
||||
echo "No deployment (build: ${CIRCLE_BRANCH}).";
|
||||
|
||||
+17
-15
@@ -23,21 +23,20 @@
|
||||
.. |MNE| image:: https://martinos.org/mne/stable/_static/mne_logo.png
|
||||
.. _MNE: https://martinos.org/mne
|
||||
|
||||
`MNE-Python <https://martinos.org/mne>`_
|
||||
========================================
|
||||
MNE-Python
|
||||
==========
|
||||
|
||||
MNE-Python is an open-source Python package for exploring, visualizing, and
|
||||
analyzing human neurophysiological data such as MEG, EEG, sEEG, ECoG, and more.
|
||||
It includes modules for data input/output, preprocessing, visualization, source
|
||||
estimation, time-frequency analysis, connectivity analysis, machine learning,
|
||||
and statistics.
|
||||
`MNE-Python software`_ is an open-source Python package for exploring,
|
||||
visualizing, and analyzing human neurophysiological data such as MEG, EEG, sEEG,
|
||||
ECoG, and more. It includes modules for data input/output, preprocessing,
|
||||
visualization, source estimation, time-frequency analysis, connectivity analysis,
|
||||
machine learning, and statistics.
|
||||
|
||||
|
||||
Documentation
|
||||
^^^^^^^^^^^^^
|
||||
|
||||
Documentation for MNE-Python is available at the
|
||||
`MNE homepage <https://martinos.org/mne>`_.
|
||||
`MNE documentation`_ for MNE-Python is available online.
|
||||
|
||||
|
||||
Get the latest code
|
||||
@@ -54,7 +53,7 @@ Alternatively, you can also download a
|
||||
|
||||
|
||||
Installing MNE-Python
|
||||
^^^^^^^^^^^^^^^^^^^^
|
||||
^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
To install the latest stable version of MNE-Python, you can use `pip <https://pip.pypa.io/en/stable/>`_ in a terminal:
|
||||
|
||||
@@ -63,8 +62,7 @@ To install the latest stable version of MNE-Python, you can use `pip <https://pi
|
||||
pip install -U mne
|
||||
|
||||
For more complete instructions and more advanced installation methods (e.g. for
|
||||
the latest development version), see the
|
||||
`getting started page <https://martinos.org/mne/getting_started.html>`_.
|
||||
the latest development version), see the `getting started page`_.
|
||||
|
||||
|
||||
Dependencies
|
||||
@@ -86,13 +84,12 @@ For full functionality, some functions require:
|
||||
|
||||
To use `NVIDIA CUDA <https://developer.nvidia.com/cuda-zone>`_ for resampling
|
||||
and FFT FIR filtering, you will also need to install the NVIDIA CUDA SDK,
|
||||
pycuda, and scikit-cuda (see the
|
||||
`getting started page <https://martinos.org/mne/getting_started.html>`_
|
||||
pycuda, and scikit-cuda (see the `getting started page`_
|
||||
for more information).
|
||||
|
||||
|
||||
Contributing to MNE-Python
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
Please see the documentation on the MNE-Python homepage:
|
||||
|
||||
@@ -142,3 +139,8 @@ MNE-Python is **BSD-licenced** (3 clause):
|
||||
(including negligence or otherwise) arising in any way out of the use
|
||||
of this software, even if advised of the possibility of such
|
||||
damage.**
|
||||
|
||||
|
||||
.. _MNE-Python software: https://martinos.org/mne
|
||||
.. _MNE documentation: http://martinos.org/mne/documentation.html
|
||||
.. _getting started page: https://martinos.org/mne/getting_started.html
|
||||
|
||||
Vendored
+2
-1
@@ -8,7 +8,8 @@
|
||||
</button>
|
||||
<ul class="dropdown-menu" aria-labelledby="dropdownMenu1">
|
||||
<li><a href="https://mne-tools.github.io/dev/index.html">Development</a></li>
|
||||
<li><a href="https://mne-tools.github.io/stable/index.html">v0.15 (stable)</a></li>
|
||||
<li><a href="https://mne-tools.github.io/stable/index.html">v0.16 (stable)</a></li>
|
||||
<li><a href="https://mne-tools.github.io/0.15/index.html">v0.15</a></li>
|
||||
<li><a href="https://mne-tools.github.io/0.14/index.html">v0.14</a></li>
|
||||
<li><a href="https://mne-tools.github.io/0.13/index.html">v0.13</a></li>
|
||||
<li><a href="https://mne-tools.github.io/0.12/index.html">v0.12</a></li>
|
||||
|
||||
@@ -41,7 +41,7 @@ the files (e.g., by updating to latest ``master``) will be reflected in
|
||||
``mne`` as soon as you restart your Python interpreter. So to update to
|
||||
the latest version of the ``master`` development branch, you can do:
|
||||
|
||||
.. code-block:: console
|
||||
.. code-block:: console
|
||||
|
||||
$ git pull origin master
|
||||
|
||||
|
||||
@@ -84,7 +84,7 @@ There are also **examples**, which contain a short use-case to highlight MNE-fun
|
||||
**More help**
|
||||
|
||||
- :ref:`Cite MNE <cite>`
|
||||
- `Mailing list <MNE mailing list>`_ for analysis talk
|
||||
- `Mailing list <https://mail.nmr.mgh.harvard.edu/mailman/listinfo/mne_analysis/>`_ for analysis talk
|
||||
- `GitHub issues <https://github.com/mne-tools/mne-python/issues/>`_ for
|
||||
requests and bug reports
|
||||
- `Gitter <https://gitter.im/mne-tools/mne-python>`_ to chat with devs
|
||||
|
||||
+36
-32
@@ -11,12 +11,9 @@ Here we provide guidance for the simplest, most well tested solution.
|
||||
1. Get a Python interpreter
|
||||
###########################
|
||||
|
||||
* **We recommend the
|
||||
Anaconda Python 3+ distribution**. Follow the installation instructions
|
||||
for your operating system
|
||||
`here <http://docs.continuum.io/anaconda/install>`_.
|
||||
|
||||
* Check the installation, which should look like a variant of this:
|
||||
* We recommend the Anaconda Python 3+ distribution.
|
||||
Follow `their installation instructions <http://docs.continuum.io/anaconda/install>`_.
|
||||
When you are done, you should see some variant of this in a terminal:
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
@@ -24,14 +21,14 @@ Here we provide guidance for the simplest, most well tested solution.
|
||||
conda 4.4.10
|
||||
Python 3.6.4 :: Continuum Analytics, Inc.
|
||||
|
||||
If it doesn't, **something went wrong**.
|
||||
If it doesn't, something went wrong.
|
||||
Look through the Anaconda documentation and Google Anaconda install
|
||||
tips (StackExchange results are often helpful).
|
||||
|
||||
2. Get MNE and its dependencies
|
||||
###############################
|
||||
|
||||
* From the command line, install the MNE dependencies to a dedicated ``mne`` Anaconda environment:
|
||||
* From the command line, install the MNE dependencies to a dedicated ``mne`` Anaconda environment.
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
@@ -39,10 +36,25 @@ Here we provide guidance for the simplest, most well tested solution.
|
||||
$ conda env create -f environment.yml
|
||||
$ source activate mne
|
||||
|
||||
Use any web browser to download ``environment.yml`` if you do not have ``curl``
|
||||
|
||||
.. raw:: html
|
||||
|
||||
<div class="row container">
|
||||
<div class="col-sm-7 container">
|
||||
<ul><li><p class="first"><b><i class="fa fa-apple"></i> macOS users only</b></p>
|
||||
|
||||
Manually update PyQt5. This step is not needed on Linux, and breaks things on Windows.
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
$ pip install --upgrade pyqt5>=5.10
|
||||
|
||||
.. raw:: html
|
||||
|
||||
</li></ul>
|
||||
|
||||
|
||||
3. Check that everything works
|
||||
##############################
|
||||
|
||||
* To check that everything worked, do:
|
||||
|
||||
@@ -56,31 +68,23 @@ Here we provide guidance for the simplest, most well tested solution.
|
||||
|
||||
If you get a new prompt with no error messages, you should be good to go!
|
||||
|
||||
.. raw:: html
|
||||
|
||||
</div>
|
||||
<div class="col-sm-4 container">
|
||||
|
||||
.. note::
|
||||
|
||||
.. raw:: html
|
||||
|
||||
<i class="fa fa-windows"></i><b>Windows users:</b>
|
||||
|
||||
If 3D plotting in Jupyter Notebooks doesn't work
|
||||
well, using the IPython magic ``%gui qt`` after importing
|
||||
MNE, Mayavi, or PySurfer should
|
||||
`help <https://github.com/ipython/ipython/issues/10384>`_, e.g.:
|
||||
|
||||
.. code:: ipython
|
||||
|
||||
from mayavi import mlab
|
||||
%gui qt
|
||||
|
||||
.. raw:: html
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<ul><li><p class="first"><b><i class="fa fa-windows"></i> Windows users only</b></p>
|
||||
|
||||
In IPython, using the magic ``%gui qt`` after importing MNE, Mayavi, or PySurfer might be
|
||||
`necessary <https://github.com/ipython/ipython/issues/10384>`_, e.g.:
|
||||
|
||||
.. code-block:: ipython
|
||||
|
||||
In [1]: from mayavi import mlab
|
||||
In [2]: %gui qt
|
||||
|
||||
.. raw:: html
|
||||
|
||||
</li></ul>
|
||||
|
||||
|
||||
* For advanced topics like how to get :ref:`CUDA` support or if you're
|
||||
having trouble, visit :ref:`advanced_setup`.
|
||||
|
||||
@@ -11,6 +11,44 @@ What's new
|
||||
|
||||
.. currentmodule:: mne
|
||||
|
||||
.. _changes_0_16_3:
|
||||
|
||||
Version 0.16.3
|
||||
--------------
|
||||
|
||||
Bug
|
||||
~~~
|
||||
|
||||
- Fix error when running LCMV on MEG channels with compensation using reference channels (like for CTF data) by `Alex Gramfort`_
|
||||
|
||||
.. _changes_0_16_2:
|
||||
|
||||
Version 0.16.2
|
||||
--------------
|
||||
|
||||
Bug
|
||||
~~~
|
||||
|
||||
- Fix bug with channel names in ``mgh70`` montage in :func:`mne.channels.read_montage` by `Eric Larson`_
|
||||
|
||||
- Fix bug in ``method='eLORETA'`` for :func:`mne.minimum_norm.apply_inverse` when using a sphere model and saved ``inv`` by `Eric Larson`_
|
||||
|
||||
- Fix bug in :class:`mne.io.Raw` where warnings were emitted when objects were deleted by `Eric Larson`_
|
||||
|
||||
- Fix bug with ``mne flash_bem`` when ``flash30`` is not used by `Eric Larson`_
|
||||
|
||||
- Fix bug in ``inst.apply_proj()`` where an average EEG reference was always added by `Eric Larson`_
|
||||
|
||||
- Fix bug in :func:`mne.time_frequency.tfr_morlet`, :func:`mne.time_frequency.tfr_multitaper`, and :func:`mne.time_frequency.tfr_stockwell` where not all data channels were picked by `Eric Larson`_
|
||||
|
||||
- Fix bug in :meth:`mne.preprocessing.ICA.plot_overlay` and :func:`mne.make_field_map` for CTF data with compensation by `Eric Larson`_
|
||||
|
||||
- Fix bug in :func:`mne.preprocessing.ICA.apply` to handle arrays as `exclude` property by `Joan Massich`_
|
||||
|
||||
- Fix error when interpolating MEG channels with compensation using reference channels (like for CTF data) by `Alex Gramfort`_
|
||||
|
||||
- Fix bug with IIR filtering axis in :func:`mne.filter.filter_data` by `Eric Larson`_
|
||||
|
||||
.. _changes_0_16:
|
||||
|
||||
Version 0.16
|
||||
|
||||
+3
-3
@@ -26,11 +26,11 @@ dependencies:
|
||||
- flake8
|
||||
- spyder
|
||||
- numexpr
|
||||
- traits>=4.6.0
|
||||
- pyface>=6
|
||||
- traitsui>=6
|
||||
- pip:
|
||||
- mne
|
||||
- "https://api.github.com/repos/enthought/traits/zipball/a99b3f64d50c5f7f28ffc01bf69419b061f9e976"
|
||||
- "https://api.github.com/repos/enthought/pyface/zipball/6a0cac149d56293482bb828a7d98122667c773be"
|
||||
- "https://api.github.com/repos/enthought/traitsui/zipball/e366ad3886d3c39bedb96e83bab447d31c4ab725"
|
||||
- "https://api.github.com/repos/enthought/mayavi/zipball/master"
|
||||
- "https://api.github.com/repos/nipy/PySurfer/zipball/master"
|
||||
- nitime
|
||||
|
||||
@@ -5,7 +5,7 @@ Plotting the full MNE solution
|
||||
|
||||
The source space that is used for the inverse computation defines a set of
|
||||
dipoles, distributed across the cortex. When visualizing a source estimate, it
|
||||
is sometimes useful to show the dipole directions, as well as their estimated
|
||||
is sometimes useful to show the dipole directions in addiion to their estimated
|
||||
magnitude.
|
||||
"""
|
||||
# Author: Marijn van Vliet <w.m.vanvliet@gmail.com>
|
||||
|
||||
+1
-1
@@ -16,7 +16,7 @@
|
||||
# Dev branch marker is: 'X.Y.devN' where N is an integer.
|
||||
#
|
||||
|
||||
__version__ = '0.16.0'
|
||||
__version__ = '0.16.2'
|
||||
|
||||
# have to import verbose first since it's needed by many things
|
||||
from .utils import (set_log_level, set_log_file, verbose, set_config,
|
||||
|
||||
@@ -116,7 +116,11 @@ def _compare_ch_names(names1, names2, bads):
|
||||
|
||||
def _check_one_ch_type(info, picks, noise_cov):
|
||||
"""Check number of sensor types and presence of noise covariance matrix."""
|
||||
# XXX : ugly hack to avoid picking subset of info with applied comps
|
||||
comps = info['comps']
|
||||
info['comps'] = []
|
||||
info_pick = pick_info(info, sel=picks)
|
||||
info['comps'] = comps
|
||||
ch_types =\
|
||||
[_contains_ch_type(info_pick, tt) for tt in ('mag', 'grad', 'eeg')]
|
||||
if sum(ch_types) > 1 and noise_cov is None:
|
||||
|
||||
@@ -622,4 +622,23 @@ def test_eig_inv():
|
||||
assert_almost_equal(a_inv, a_inv_eig)
|
||||
|
||||
|
||||
@testing.requires_testing_data
|
||||
def test_lcmv_ctf_comp():
|
||||
"""Test interpolation with compensated CTF data."""
|
||||
ctf_dir = op.join(testing.data_path(download=False), 'CTF')
|
||||
raw_fname = op.join(ctf_dir, 'somMDYO-18av.ds')
|
||||
raw = mne.io.read_raw_ctf(raw_fname, preload=True)
|
||||
|
||||
events = mne.make_fixed_length_events(raw, duration=0.2)[:2]
|
||||
epochs = mne.Epochs(raw, events, tmin=0., tmax=0.2)
|
||||
evoked = epochs.average()
|
||||
|
||||
with warnings.catch_warnings(record=True):
|
||||
data_cov = mne.compute_covariance(epochs)
|
||||
fwd = mne.make_forward_solution(evoked.info, None,
|
||||
mne.setup_volume_source_space(pos=15.0),
|
||||
mne.make_sphere_model())
|
||||
filters = mne.beamformer.make_lcmv(evoked.info, fwd, data_cov)
|
||||
assert 'weights' in filters
|
||||
|
||||
run_tests_if_main()
|
||||
|
||||
+11
-6
@@ -1668,7 +1668,11 @@ def convert_flash_mris(subject, flash30=True, convert=True, unwarp=False,
|
||||
echos_done += 1
|
||||
# Step 1b : Run grad_unwarp on converted files
|
||||
os.chdir(op.join(mri_dir, "flash"))
|
||||
files = glob.glob("mef*.mgz")
|
||||
template = "mef*.mgz"
|
||||
files = glob.glob(template)
|
||||
if len(files) == 0:
|
||||
raise ValueError('No suitable source files found (%s)'
|
||||
% op.join(os.getcwd(), template))
|
||||
if unwarp:
|
||||
logger.info("\n---- Unwarp mgz data sets ----")
|
||||
for infile in files:
|
||||
@@ -1705,11 +1709,12 @@ def convert_flash_mris(subject, flash30=True, convert=True, unwarp=False,
|
||||
else:
|
||||
logger.info("\n---- Averaging flash5 echoes ----")
|
||||
os.chdir('parameter_maps')
|
||||
if unwarp:
|
||||
files = glob.glob("mef05*u.mgz")
|
||||
else:
|
||||
files = glob.glob("mef05*.mgz")
|
||||
cmd = ['mri_average', '-noconform', files, 'flash5.mgz']
|
||||
template = "mef05*u.mgz" if unwarp else "mef05*.mgz"
|
||||
files = glob.glob(template)
|
||||
if len(files) == 0:
|
||||
raise ValueError('No suitable source files found (%s)'
|
||||
% op.join(os.getcwd(), template))
|
||||
cmd = ['mri_average', '-noconform'] + files + ['flash5.mgz']
|
||||
run_subprocess(cmd, env=env)
|
||||
if op.exists('flash5_reg.mgz'):
|
||||
os.remove('flash5_reg.mgz')
|
||||
|
||||
@@ -140,13 +140,13 @@ EEG057
|
||||
EEG058
|
||||
EEG059
|
||||
EEG060
|
||||
EEG061
|
||||
EEG062
|
||||
EEG063
|
||||
EEG064
|
||||
EEG065
|
||||
EEG066
|
||||
EEG067
|
||||
EEG068
|
||||
EEG069
|
||||
EEG070
|
||||
EEG070
|
||||
EEG071
|
||||
EEG072
|
||||
EEG073
|
||||
EEG074
|
||||
@@ -171,8 +171,10 @@ def _interpolate_bads_meg(inst, mode='accurate', verbose=None):
|
||||
If not None, override default verbose level (see :func:`mne.verbose`
|
||||
and :ref:`Logging documentation <tut_logging>` for more).
|
||||
"""
|
||||
picks_meg = pick_types(inst.info, meg=True, eeg=False, exclude=[])
|
||||
picks_good = pick_types(inst.info, meg=True, eeg=False, exclude='bads')
|
||||
picks_meg = pick_types(inst.info, meg=True, eeg=False,
|
||||
ref_meg=True, exclude=[])
|
||||
picks_good = pick_types(inst.info, meg=True, eeg=False,
|
||||
ref_meg=True, exclude='bads')
|
||||
meg_ch_names = [inst.info['ch_names'][p] for p in picks_meg]
|
||||
bads_meg = [ch for ch in inst.info['bads'] if ch in meg_ch_names]
|
||||
|
||||
@@ -186,7 +188,9 @@ def _interpolate_bads_meg(inst, mode='accurate', verbose=None):
|
||||
# return without doing anything if there are no meg channels
|
||||
if len(picks_meg) == 0 or len(picks_bad) == 0:
|
||||
return
|
||||
info_from = pick_info(inst.info, picks_good)
|
||||
info_to = pick_info(inst.info, picks_bad)
|
||||
inst_info = inst.info.copy()
|
||||
inst_info['comps'] = []
|
||||
info_from = pick_info(inst_info, picks_good)
|
||||
info_to = pick_info(inst_info, picks_bad)
|
||||
mapping = _map_meg_channels(info_from, info_to, mode=mode)
|
||||
_do_interp_dots(inst, mapping, picks_good, picks_bad)
|
||||
|
||||
@@ -8,6 +8,7 @@ from nose.tools import assert_raises, assert_equal, assert_true
|
||||
|
||||
from mne import io, pick_types, pick_channels, read_events, Epochs
|
||||
from mne.channels.interpolation import _make_interpolation_matrix
|
||||
from mne.datasets import testing
|
||||
from mne.utils import run_tests_if_main
|
||||
|
||||
base_dir = op.join(op.dirname(__file__), '..', '..', 'io', 'tests', 'data')
|
||||
@@ -154,4 +155,15 @@ def test_interpolation():
|
||||
assert_true(np.corrcoef(data1, data2)[0, 1] > thresh)
|
||||
|
||||
|
||||
@testing.requires_testing_data
|
||||
def test_interpolation_ctf_comp():
|
||||
"""Test interpolation with compensated CTF data."""
|
||||
ctf_dir = op.join(testing.data_path(download=False), 'CTF')
|
||||
raw_fname = op.join(ctf_dir, 'somMDYO-18av.ds')
|
||||
raw = io.read_raw_ctf(raw_fname, preload=True)
|
||||
raw.info['bads'] = [raw.ch_names[5], raw.ch_names[-5]]
|
||||
raw.interpolate_bads(mode='fast')
|
||||
assert raw.info['bads'] == []
|
||||
|
||||
|
||||
run_tests_if_main()
|
||||
|
||||
@@ -553,6 +553,10 @@ def test_set_montage():
|
||||
assert_true((orig_pos != new_pos).all())
|
||||
r0 = _fit_sphere(new_pos)[1]
|
||||
assert_allclose(r0, [0., -0.016, 0.], atol=1e-3)
|
||||
# mgh70 has no 61/62/63/64 (these are EOG/ECG)
|
||||
mon = read_montage('mgh70')
|
||||
assert 'EEG061' not in mon.ch_names
|
||||
assert 'EEG074' in mon.ch_names
|
||||
|
||||
|
||||
def _check_roundtrip(montage, fname):
|
||||
|
||||
+5
-8
@@ -438,16 +438,17 @@ def _filtfilt(x, iir_params, picks, n_jobs, copy):
|
||||
"""Call filtfilt."""
|
||||
# set up array for filtering, reshape to 2D, operate on last axis
|
||||
from scipy.signal import filtfilt
|
||||
padlen = min(iir_params['padlen'], len(x))
|
||||
padlen = min(iir_params['padlen'], x.shape[-1] - 1)
|
||||
n_jobs = check_n_jobs(n_jobs)
|
||||
x, orig_shape, picks = _prep_for_filtering(x, copy, picks)
|
||||
if 'sos' in iir_params:
|
||||
sosfiltfilt = get_sosfiltfilt()
|
||||
fun = partial(sosfiltfilt, sos=iir_params['sos'], padlen=padlen)
|
||||
fun = partial(sosfiltfilt, sos=iir_params['sos'], padlen=padlen,
|
||||
axis=-1)
|
||||
_check_coefficients(iir_params['sos'])
|
||||
else:
|
||||
fun = partial(filtfilt, b=iir_params['b'], a=iir_params['a'],
|
||||
padlen=padlen)
|
||||
padlen=padlen, axis=-1)
|
||||
_check_coefficients((iir_params['b'], iir_params['a']))
|
||||
if n_jobs == 1:
|
||||
for p in picks:
|
||||
@@ -645,11 +646,7 @@ def construct_iir_filter(iir_params, f_pass=None, f_stop=None, sfreq=None,
|
||||
system = (iir_params['b'], iir_params['a'])
|
||||
output = 'ba'
|
||||
else:
|
||||
output = iir_params.get('output', None)
|
||||
if output is None:
|
||||
warn('The default output type is "ba" in 0.13 but will change '
|
||||
'to "sos" in 0.14')
|
||||
output = 'ba'
|
||||
output = iir_params.get('output', 'sos')
|
||||
if not isinstance(output, string_types) or output not in ('ba', 'sos'):
|
||||
raise ValueError('Output must be "ba" or "sos", got %s'
|
||||
% (output,))
|
||||
|
||||
@@ -281,7 +281,10 @@ def _make_surface_mapping(info, surf, ch_type='meg', trans=None, mode='fast',
|
||||
logger.info('Prepare EEG mapping...')
|
||||
if len(picks) == 0:
|
||||
raise RuntimeError('cannot map, no channels found')
|
||||
chs = pick_info(info, picks)['chs']
|
||||
# XXX this code does not do any checking for compensation channels,
|
||||
# but it seems like this must be intentional from the ref_meg=False
|
||||
# (presumably from the C code)
|
||||
chs = [info['chs'][pick] for pick in picks]
|
||||
|
||||
# create coil defs in head coordinates
|
||||
if ch_type == 'meg':
|
||||
|
||||
@@ -410,14 +410,14 @@ def read_forward_solution(fname, include=(), exclude=(), verbose=None):
|
||||
Forward solutions, which are derived from an original forward solution with
|
||||
free orientation, are always stored on disk as forward solution with free
|
||||
orientation in X/Y/Z RAS coordinates. To apply any transformation to the
|
||||
forward operator (surface orientation, fixed orienation) please apply
|
||||
forward operator (surface orientation, fixed orientation) please apply
|
||||
:func:`convert_forward_solution` after reading the forward solution with
|
||||
:func:`read_forward_solution`.
|
||||
|
||||
Forward solutions, which are derived from an original forward solution with
|
||||
fixed orientation, are stored on disk as forward solution with fixed
|
||||
surface-based orientations. Please note that the transformation to
|
||||
surface-based, fixed orienation cannot be reverted after loading the
|
||||
surface-based, fixed orientation cannot be reverted after loading the
|
||||
forward solution with :func:`read_forward_solution`.
|
||||
"""
|
||||
check_fname(fname, 'forward', ('-fwd.fif', '-fwd.fif.gz',
|
||||
@@ -758,14 +758,14 @@ def write_forward_solution(fname, fwd, overwrite=False, verbose=None):
|
||||
Forward solutions, which are derived from an original forward solution with
|
||||
free orientation, are always stored on disk as forward solution with free
|
||||
orientation in X/Y/Z RAS coordinates. Transformations (surface orientation,
|
||||
fixed orienation) will be reverted. To reapply any transformation to the
|
||||
fixed orientation) will be reverted. To reapply any transformation to the
|
||||
forward operator please apply :func:`convert_forward_solution` after
|
||||
reading the forward solution with :func:`read_forward_solution`.
|
||||
|
||||
Forward solutions, which are derived from an original forward solution with
|
||||
fixed orientation, are stored on disk as forward solution with fixed
|
||||
surface-based orientations. Please note that the transformation to
|
||||
surface-based, fixed orienation cannot be reverted after loading the
|
||||
surface-based, fixed orientation cannot be reverted after loading the
|
||||
forward solution with :func:`read_forward_solution`.
|
||||
"""
|
||||
check_fname(fname, 'forward', ('-fwd.fif', '-fwd.fif.gz',
|
||||
|
||||
@@ -15,13 +15,15 @@ from mne.forward._make_forward import _create_meg_coils
|
||||
from mne.forward._field_interpolation import _setup_dots
|
||||
from mne.surface import get_meg_helmet_surf, get_head_surf
|
||||
from mne.datasets import testing
|
||||
from mne import read_evokeds, pick_types
|
||||
from mne import read_evokeds, pick_types, make_fixed_length_events, Epochs
|
||||
from mne.io import read_raw_fif
|
||||
from mne.externals.six.moves import zip
|
||||
from mne.utils import run_tests_if_main
|
||||
|
||||
|
||||
base_dir = op.join(op.dirname(__file__), '..', '..', 'io', 'tests', 'data')
|
||||
evoked_fname = op.join(base_dir, 'test-ave.fif')
|
||||
raw_ctf_fname = op.join(base_dir, 'test_ctf_raw.fif')
|
||||
|
||||
data_path = testing.data_path(download=False)
|
||||
trans_fname = op.join(data_path, 'MEG', 'sample',
|
||||
@@ -29,6 +31,19 @@ trans_fname = op.join(data_path, 'MEG', 'sample',
|
||||
subjects_dir = op.join(data_path, 'subjects')
|
||||
|
||||
|
||||
@testing.requires_testing_data
|
||||
def test_field_map_ctf():
|
||||
"""Test that field mapping can be done with CTF data."""
|
||||
raw = read_raw_fif(raw_ctf_fname).crop(0, 1)
|
||||
raw.apply_gradient_compensation(3)
|
||||
events = make_fixed_length_events(raw, duration=0.5)
|
||||
evoked = Epochs(raw, events).average()
|
||||
evoked.pick_channels(evoked.ch_names[:50]) # crappy mapping but faster
|
||||
# smoke test
|
||||
make_field_map(evoked, trans=trans_fname, subject='sample',
|
||||
subjects_dir=subjects_dir)
|
||||
|
||||
|
||||
def test_legendre_val():
|
||||
"""Test Legendre polynomial (derivative) equivalence."""
|
||||
rng = np.random.RandomState(0)
|
||||
|
||||
+2
-1
@@ -727,7 +727,8 @@ class BaseRaw(ProjMixin, ContainsMixin, UpdateChannelsMixin,
|
||||
|
||||
def __del__(self): # noqa: D105
|
||||
# remove file for memmap
|
||||
if hasattr(self, '_data') and hasattr(self._data, 'filename'):
|
||||
if hasattr(self, '_data') and \
|
||||
getattr(self._data, 'filename', None) is not None:
|
||||
# First, close the file out; happens automatically on del
|
||||
filename = self._data.filename
|
||||
del self._data
|
||||
|
||||
+1
-1
@@ -735,7 +735,7 @@ FIFF.FIFF_UNIT_MHO = 110 # one per ohm
|
||||
FIFF.FIFF_UNIT_WB = 111 # weber
|
||||
FIFF.FIFF_UNIT_T = 112 # tesla
|
||||
FIFF.FIFF_UNIT_H = 113 # Henry
|
||||
FIFF.FIFF_UNIT_CEL = 114 # celcius
|
||||
FIFF.FIFF_UNIT_CEL = 114 # celsius
|
||||
FIFF.FIFF_UNIT_LM = 115 # lumen
|
||||
FIFF.FIFF_UNIT_LX = 116 # lux
|
||||
#
|
||||
|
||||
@@ -229,7 +229,7 @@ def test_rank_estimation():
|
||||
n_proj = len(raw.info['projs'])
|
||||
assert_array_equal(raw.estimate_rank(tstart=0, tstop=3.,
|
||||
scalings=scalings),
|
||||
expected_rank - (1 if 'sss' in fname else n_proj))
|
||||
expected_rank - (0 if 'sss' in fname else n_proj))
|
||||
|
||||
|
||||
@testing.requires_testing_data
|
||||
@@ -853,8 +853,12 @@ def test_filter():
|
||||
|
||||
# ... and that inplace changes are inplace
|
||||
raw_copy = raw.copy()
|
||||
assert np.may_share_memory(raw._data, raw._data)
|
||||
assert not np.may_share_memory(raw_copy._data, raw._data)
|
||||
# this could be assert_array_equal but we do this to mirror the call below
|
||||
assert (raw._data[0] == raw_copy._data[0]).all()
|
||||
raw_copy.filter(None, 20., n_jobs=2, **filter_params)
|
||||
assert_true(raw._data[0, 0] != raw_copy._data[0, 0])
|
||||
assert not (raw._data[0] == raw_copy._data[0]).all()
|
||||
assert_equal(raw.copy().filter(None, 20., **filter_params)._data,
|
||||
raw_copy._data)
|
||||
|
||||
|
||||
+1
-1
@@ -812,5 +812,5 @@ def _get_channel_types(info, picks=None, unique=True,
|
||||
if idx in picks]
|
||||
if restrict_data_types is True:
|
||||
ch_types = [ch_type for ch_type in ch_types
|
||||
if ch_type not in _DATA_CH_TYPES_SPLIT]
|
||||
if ch_type in _DATA_CH_TYPES_SPLIT]
|
||||
return set(ch_types) if unique is True else ch_types
|
||||
|
||||
+5
-4
@@ -234,8 +234,8 @@ class ProjMixin(object):
|
||||
'Setting proj attribute to True.')
|
||||
return self
|
||||
|
||||
_projector, info = setup_proj(deepcopy(self.info), activate=True,
|
||||
verbose=self.verbose)
|
||||
_projector, info = setup_proj(deepcopy(self.info), add_eeg_ref=False,
|
||||
activate=True, verbose=self.verbose)
|
||||
# let's not raise a RuntimeError here, otherwise interactive plotting
|
||||
if _projector is None: # won't be fun.
|
||||
logger.info('The projections don\'t apply to these data.'
|
||||
@@ -276,8 +276,9 @@ class ProjMixin(object):
|
||||
if any(self.info['projs'][ii]['active'] for ii in idx):
|
||||
raise ValueError('Cannot remove projectors that have already '
|
||||
'been applied')
|
||||
self.info['projs'] = [p for pi, p in enumerate(self.info['projs'])
|
||||
if pi not in idx]
|
||||
keep = np.ones(len(self.info['projs']))
|
||||
keep[idx] = False # works with negative indexing and does checks
|
||||
self.info['projs'] = [p for p, k in zip(self.info['projs'], keep) if k]
|
||||
return self
|
||||
|
||||
def plot_projs_topomap(self, ch_type=None, layout=None, axes=None):
|
||||
|
||||
@@ -117,7 +117,10 @@ def _compute_eloreta_inv(G, W, n_orient, n_nzero, lambda2, force_equal):
|
||||
W_inv[:] = 1. / W
|
||||
else:
|
||||
for ii in range(n_src):
|
||||
W_inv[ii] = linalg.pinv2(W[ii])
|
||||
# Here we use a single-precision-suitable `rcond` (given our
|
||||
# 3x3 matrix size) because the inv could be saved in single
|
||||
# precision.
|
||||
W_inv[ii] = linalg.pinv2(W[ii], rcond=1e-7)
|
||||
|
||||
# Weight the gain matrix
|
||||
W_inv_Gt = np.empty_like(G).T
|
||||
@@ -138,7 +141,7 @@ def _sqrtm_sym(C):
|
||||
"""Compute the square root of a symmetric matrix."""
|
||||
# Same as linalg.sqrtm(C) but faster, also yields the eigenvalues
|
||||
s, u = linalg.eigh(C)
|
||||
mask = np.abs(s) > s.max() * 1e-12
|
||||
mask = s > s.max() * 1e-7
|
||||
u = u[:, mask]
|
||||
s = np.sqrt(s[mask])
|
||||
a = np.dot(s * u, u.T)
|
||||
|
||||
@@ -18,7 +18,7 @@ from mne.source_estimate import read_source_estimate, VolSourceEstimate
|
||||
from mne import (read_cov, read_forward_solution, read_evokeds, pick_types,
|
||||
pick_types_forward, make_forward_solution, EvokedArray,
|
||||
convert_forward_solution, Covariance, combine_evoked,
|
||||
SourceEstimate)
|
||||
SourceEstimate, make_sphere_model, make_ad_hoc_cov)
|
||||
from mne.io import read_raw_fif, Info
|
||||
from mne.minimum_norm.inverse import (apply_inverse, read_inverse_operator,
|
||||
apply_inverse_raw, apply_inverse_epochs,
|
||||
@@ -377,6 +377,39 @@ def test_localization_bias():
|
||||
assert lower <= perc <= upper, method
|
||||
|
||||
|
||||
@testing.requires_testing_data
|
||||
def test_apply_inverse_sphere():
|
||||
"""Test applying an inverse with a sphere model (rank-deficient)."""
|
||||
evoked = _get_evoked()
|
||||
evoked.pick_channels(evoked.ch_names[:306:8])
|
||||
evoked.info['projs'] = []
|
||||
cov = make_ad_hoc_cov(evoked.info)
|
||||
sphere = make_sphere_model('auto', 'auto', evoked.info)
|
||||
fwd = read_forward_solution(fname_fwd)
|
||||
vertices = [fwd['src'][0]['vertno'][::5],
|
||||
fwd['src'][1]['vertno'][::5]]
|
||||
stc = SourceEstimate(np.zeros((sum(len(v) for v in vertices), 1)),
|
||||
vertices, 0., 1.)
|
||||
fwd = restrict_forward_to_stc(fwd, stc)
|
||||
fwd = make_forward_solution(evoked.info, fwd['mri_head_t'], fwd['src'],
|
||||
sphere, mindist=5.)
|
||||
evoked = EvokedArray(fwd['sol']['data'].copy(), evoked.info)
|
||||
assert fwd['sol']['nrow'] == 39
|
||||
assert fwd['nsource'] == 101
|
||||
assert fwd['sol']['ncol'] == 303
|
||||
tempdir = _TempDir()
|
||||
temp_fname = op.join(tempdir, 'temp-inv.fif')
|
||||
inv = make_inverse_operator(evoked.info, fwd, cov, loose=1.)
|
||||
# This forces everything to be float32
|
||||
write_inverse_operator(temp_fname, inv)
|
||||
inv = read_inverse_operator(temp_fname)
|
||||
stc = apply_inverse(evoked, inv, method='eLORETA',
|
||||
method_params=dict(eps=1e-3))
|
||||
# assert zero localization bias
|
||||
assert_array_equal(np.argmax(stc.data, axis=0),
|
||||
np.repeat(np.arange(101), 3))
|
||||
|
||||
|
||||
@pytest.mark.slowtest
|
||||
@testing.requires_testing_data
|
||||
def test_apply_inverse_operator():
|
||||
|
||||
@@ -456,7 +456,7 @@ def compute_source_psd(raw, inverse_operator, lambda2=1. / 9., method="dSPM",
|
||||
stc : SourceEstimate | VolSourceEstimate
|
||||
The PSD (in dB) of each of the sources.
|
||||
"""
|
||||
from scipy.signal import hanning
|
||||
from scipy.signal import hann
|
||||
_check_ori(pick_ori, inverse_operator['source_ori'])
|
||||
|
||||
logger.info('Considering frequencies %g ... %g Hz' % (fmin, fmax))
|
||||
@@ -473,7 +473,7 @@ def compute_source_psd(raw, inverse_operator, lambda2=1. / 9., method="dSPM",
|
||||
stop = raw.time_as_index(tmax)[0] + 1
|
||||
n_fft = int(n_fft)
|
||||
Fs = raw.info['sfreq']
|
||||
window = hanning(n_fft)
|
||||
window = hann(n_fft)
|
||||
freqs = fftpack.fftfreq(n_fft, 1. / Fs)
|
||||
freqs_mask = (freqs >= 0) & (freqs >= fmin) & (freqs <= fmax)
|
||||
freqs = freqs[freqs_mask]
|
||||
|
||||
@@ -1260,14 +1260,16 @@ class ICA(ContainsMixin):
|
||||
'type')
|
||||
return out
|
||||
|
||||
def _check_exclude(self, exclude):
|
||||
if exclude is None:
|
||||
return list(set(self.exclude))
|
||||
else:
|
||||
return list(set(self.exclude + exclude))
|
||||
|
||||
def _apply_raw(self, raw, include, exclude, n_pca_components, start, stop):
|
||||
"""Aux method."""
|
||||
_check_preload(raw, "ica.apply")
|
||||
|
||||
if exclude is None:
|
||||
exclude = list(set(self.exclude))
|
||||
else:
|
||||
exclude = list(set(self.exclude + exclude))
|
||||
exclude = self._check_exclude(exclude)
|
||||
|
||||
if n_pca_components is not None:
|
||||
self.n_pca_components = n_pca_components
|
||||
@@ -1288,6 +1290,7 @@ class ICA(ContainsMixin):
|
||||
def _apply_epochs(self, epochs, include, exclude, n_pca_components):
|
||||
"""Aux method."""
|
||||
_check_preload(epochs, "ica.apply")
|
||||
exclude = self._check_exclude(exclude)
|
||||
|
||||
picks = pick_types(epochs.info, meg=False, ref_meg=False,
|
||||
include=self.ch_names,
|
||||
@@ -1317,6 +1320,7 @@ class ICA(ContainsMixin):
|
||||
|
||||
def _apply_evoked(self, evoked, include, exclude, n_pca_components):
|
||||
"""Aux method."""
|
||||
exclude = self._check_exclude(exclude)
|
||||
picks = pick_types(evoked.info, meg=False, ref_meg=False,
|
||||
include=self.ch_names,
|
||||
exclude='bads')
|
||||
|
||||
@@ -145,7 +145,7 @@ def test_mne_python_vs_eeglab():
|
||||
|
||||
w_change_eeglab = 1e-7 if N > 32 else 1e-6
|
||||
|
||||
# Call mne_python infomax version using the following sintax
|
||||
# Call mne_python infomax version using the following syntax
|
||||
# to obtain the same result than eeglab version
|
||||
unmixing = infomax(
|
||||
Y.T, extended=use_extended, random_state=random_state,
|
||||
|
||||
@@ -442,13 +442,14 @@ def test_ica_additional(method):
|
||||
assert_true(ica.pca_components_.shape == (4, len(picks)))
|
||||
assert_true(sources.shape[1] == ica.n_components_)
|
||||
|
||||
for exclude in [[], [0]]:
|
||||
for exclude in [[], [0], np.array([1, 2, 3])]:
|
||||
ica.exclude = exclude
|
||||
ica.labels_ = {'foo': [0]}
|
||||
ica.save(test_ica_fname)
|
||||
ica_read = read_ica(test_ica_fname)
|
||||
assert_true(ica.exclude == ica_read.exclude)
|
||||
assert_true(list(ica.exclude) == ica_read.exclude)
|
||||
assert_equal(ica.labels_, ica_read.labels_)
|
||||
ica.apply(raw)
|
||||
ica.exclude = []
|
||||
ica.apply(raw, exclude=[1])
|
||||
assert_true(ica.exclude == [])
|
||||
|
||||
@@ -1959,7 +1959,7 @@ class VectorSourceEstimate(_BaseSurfaceSourceEstimate):
|
||||
self.subject, self.verbose)
|
||||
|
||||
@copy_function_doc_to_method_doc(plot_vector_source_estimates)
|
||||
def plot(self, subject=None, hemi='lh', colormap='auto', time_label='auto',
|
||||
def plot(self, subject=None, hemi='lh', colormap='hot', time_label='auto',
|
||||
smoothing_steps=10, transparent=None, brain_alpha=0.4,
|
||||
overlay_alpha=None, vector_alpha=1.0, scale_factor=None,
|
||||
time_viewer=False, subjects_dir=None, figure=None, views='lat',
|
||||
|
||||
@@ -8,7 +8,7 @@ import numpy as np
|
||||
|
||||
# hardcoded external test results, manually transferred
|
||||
test_external = {
|
||||
# SPSS, manually conducted analyis
|
||||
# SPSS, manually conducted analysis
|
||||
'spss_fvals': np.array([2.568, 0.240, 1.756]),
|
||||
'spss_pvals_uncorrected': np.array([0.126, 0.788, 0.186]),
|
||||
'spss_pvals_corrected': np.array([0.126, 0.784, 0.192]),
|
||||
|
||||
@@ -30,6 +30,7 @@ from mne.tests.common import assert_naming, assert_snr
|
||||
from mne.utils import _TempDir, requires_version, run_tests_if_main
|
||||
from mne.io.proc_history import _get_sss_rank
|
||||
from mne.io.pick import channel_type, _picks_by_type, _DATA_CH_TYPES_SPLIT
|
||||
from mne.io.proj import _has_eeg_average_ref_proj
|
||||
from mne.datasets import testing
|
||||
from mne.event import make_fixed_length_events
|
||||
|
||||
@@ -406,8 +407,10 @@ def test_rank():
|
||||
|
||||
# Now do some more comprehensive tests
|
||||
raw_sample = read_raw_fif(raw_fname)
|
||||
assert not _has_eeg_average_ref_proj(raw_sample.info['projs'])
|
||||
|
||||
raw_sss = read_raw_fif(hp_fif_fname)
|
||||
assert not _has_eeg_average_ref_proj(raw_sss.info['projs'])
|
||||
raw_sss.add_proj(compute_proj_raw(raw_sss))
|
||||
|
||||
cov_sample = compute_raw_covariance(raw_sample)
|
||||
@@ -460,10 +463,6 @@ def test_rank():
|
||||
n_eeg, n_mag, n_grad = [ch_types.count(k) for k in
|
||||
['eeg', 'mag', 'grad']]
|
||||
n_meg = n_mag + n_grad
|
||||
if ch_type in ('all', 'eeg'):
|
||||
n_projs_eeg = 1
|
||||
else:
|
||||
n_projs_eeg = 0
|
||||
|
||||
# check sss
|
||||
if len(this_very_info['proc_history']) > 0:
|
||||
@@ -473,8 +472,6 @@ def test_rank():
|
||||
n_free = 0
|
||||
# - n_projs XXX clarify
|
||||
expected_rank = n_free + n_eeg
|
||||
if n_projs > 0 and ch_type in ('all', 'eeg'):
|
||||
expected_rank -= n_projs_eeg
|
||||
else:
|
||||
expected_rank = n_meg + n_eeg - n_projs
|
||||
|
||||
|
||||
+53
-50
@@ -4,7 +4,6 @@ import warnings
|
||||
import numpy as np
|
||||
from numpy.testing import (assert_array_almost_equal, assert_almost_equal,
|
||||
assert_array_equal, assert_allclose)
|
||||
from nose.tools import assert_equal, assert_true, assert_raises
|
||||
import pytest
|
||||
from scipy.signal import resample as sp_resample, butter
|
||||
from scipy.fftpack import fft, fftfreq
|
||||
@@ -24,6 +23,14 @@ warnings.simplefilter('always') # enable b/c these tests throw warnings
|
||||
rng = np.random.RandomState(0)
|
||||
|
||||
|
||||
@requires_version('scipy', '0.16')
|
||||
def test_filter_array():
|
||||
"""Test filtering an array."""
|
||||
for data in (np.zeros((11, 1, 10)), np.zeros((9, 1, 10))):
|
||||
filter_data(data, 512., 8, 12, method='iir',
|
||||
iir_params=dict(ftype='butterworth', order=2))
|
||||
|
||||
|
||||
@requires_mne
|
||||
def test_mne_c_design():
|
||||
"""Test MNE-C filter design."""
|
||||
@@ -65,12 +72,11 @@ def test_estimate_ringing():
|
||||
(0.001, (3000, 6000)), # 4758
|
||||
(0.0001, (30000, 60000))): # 37993
|
||||
n_ring = estimate_ringing_samples(butter(3, thresh, output=kind))
|
||||
assert_true(lims[0] <= n_ring <= lims[1],
|
||||
msg='%s %s: %s <= %s <= %s'
|
||||
% (kind, thresh, lims[0], n_ring, lims[1]))
|
||||
with warnings.catch_warnings(record=True) as w:
|
||||
assert_equal(estimate_ringing_samples(butter(4, 0.00001)), 100000)
|
||||
assert_true(any('properly estimate' in str(ww.message) for ww in w))
|
||||
assert lims[0] <= n_ring <= lims[1], (
|
||||
'%s %s: %s <= %s <= %s'
|
||||
% (kind, thresh, lims[0], n_ring, lims[1]))
|
||||
with pytest.warns(RuntimeWarning, match='properly estimate'):
|
||||
assert estimate_ringing_samples(butter(4, 0.00001)) == 100000
|
||||
|
||||
|
||||
def test_1d_filter():
|
||||
@@ -92,7 +98,7 @@ def test_1d_filter():
|
||||
if phase == 'zero':
|
||||
# only allow zero-phase for odd-length filters
|
||||
if n_filter % 2 == 0:
|
||||
assert_raises(RuntimeError, _overlap_add_filter,
|
||||
pytest.raises(RuntimeError, _overlap_add_filter,
|
||||
x[np.newaxis], h, phase=phase)
|
||||
continue
|
||||
shift = (len(h) - 1) // 2
|
||||
@@ -111,7 +117,7 @@ def test_1d_filter():
|
||||
# remove padding
|
||||
if n_pad > 0:
|
||||
x_expected = x_expected[n_pad:len(x_expected) - n_pad]
|
||||
assert_equal(len(x_expected), len(x))
|
||||
assert len(x_expected) == len(x)
|
||||
# make sure we actually set things up reasonably
|
||||
if filter_type == 'identity':
|
||||
out = x_pad.copy()
|
||||
@@ -119,9 +125,9 @@ def test_1d_filter():
|
||||
out = out[:len(x)]
|
||||
out = np.concatenate((out, np.zeros(max(len(x) -
|
||||
len(out), 0))))
|
||||
assert_equal(len(out), len(x))
|
||||
assert len(out) == len(x)
|
||||
assert_allclose(out, x_expected)
|
||||
assert_equal(len(x_expected), len(x))
|
||||
assert len(x_expected) == len(x)
|
||||
|
||||
# compute our version
|
||||
for n_fft in (None, 32, 128, 129, 1023, 1024, 1025, 2048):
|
||||
@@ -131,7 +137,7 @@ def test_1d_filter():
|
||||
if phase == 'zero-double':
|
||||
min_fft = 2 * min_fft - 1
|
||||
if n_fft is not None and n_fft < min_fft:
|
||||
assert_raises(ValueError, _overlap_add_filter,
|
||||
pytest.raises(ValueError, _overlap_add_filter,
|
||||
x_copy, h, n_fft, phase=phase)
|
||||
else:
|
||||
x_filtered = _overlap_add_filter(
|
||||
@@ -145,39 +151,39 @@ def test_iir_stability():
|
||||
sig = np.empty(1000)
|
||||
sfreq = 1000
|
||||
# This will make an unstable filter, should throw RuntimeError
|
||||
assert_raises(RuntimeError, filter_data, sig, sfreq, 0.6, None,
|
||||
pytest.raises(RuntimeError, filter_data, sig, sfreq, 0.6, None,
|
||||
method='iir', iir_params=dict(ftype='butter', order=8,
|
||||
output='ba'))
|
||||
# This one should work just fine
|
||||
filter_data(sig, sfreq, 0.6, None, method='iir',
|
||||
iir_params=dict(ftype='butter', order=8, output='sos'))
|
||||
# bad system type
|
||||
assert_raises(ValueError, filter_data, sig, sfreq, 0.6, None, method='iir',
|
||||
pytest.raises(ValueError, filter_data, sig, sfreq, 0.6, None, method='iir',
|
||||
iir_params=dict(ftype='butter', order=8, output='foo'))
|
||||
# missing ftype
|
||||
assert_raises(RuntimeError, filter_data, sig, sfreq, 0.6, None,
|
||||
pytest.raises(RuntimeError, filter_data, sig, sfreq, 0.6, None,
|
||||
method='iir', iir_params=dict(order=8, output='sos'))
|
||||
# bad ftype
|
||||
assert_raises(RuntimeError, filter_data, sig, sfreq, 0.6, None,
|
||||
pytest.raises(RuntimeError, filter_data, sig, sfreq, 0.6, None,
|
||||
method='iir',
|
||||
iir_params=dict(order=8, ftype='foo', output='sos'))
|
||||
# missing gstop
|
||||
assert_raises(RuntimeError, filter_data, sig, sfreq, 0.6, None,
|
||||
pytest.raises(RuntimeError, filter_data, sig, sfreq, 0.6, None,
|
||||
method='iir', iir_params=dict(gpass=0.5, output='sos'))
|
||||
# can't pass iir_params if method='fft'
|
||||
assert_raises(ValueError, filter_data, sig, sfreq, 0.1, None,
|
||||
pytest.raises(ValueError, filter_data, sig, sfreq, 0.1, None,
|
||||
method='fft', iir_params=dict(ftype='butter', order=2,
|
||||
output='sos'))
|
||||
# method must be string
|
||||
assert_raises(TypeError, filter_data, sig, sfreq, 0.1, None,
|
||||
pytest.raises(TypeError, filter_data, sig, sfreq, 0.1, None,
|
||||
method=1)
|
||||
# unknown method
|
||||
assert_raises(ValueError, filter_data, sig, sfreq, 0.1, None,
|
||||
pytest.raises(ValueError, filter_data, sig, sfreq, 0.1, None,
|
||||
method='blah')
|
||||
# bad iir_params
|
||||
assert_raises(TypeError, filter_data, sig, sfreq, 0.1, None,
|
||||
pytest.raises(TypeError, filter_data, sig, sfreq, 0.1, None,
|
||||
method='iir', iir_params='blah')
|
||||
assert_raises(ValueError, filter_data, sig, sfreq, 0.1, None,
|
||||
pytest.raises(ValueError, filter_data, sig, sfreq, 0.1, None,
|
||||
method='fft', iir_params=dict())
|
||||
|
||||
# should pass because dafault trans_bandwidth is not relevant
|
||||
@@ -211,8 +217,8 @@ def test_notch_filters():
|
||||
a += np.sum([np.sin(2 * np.pi * f * t) for f in freqs], axis=0)
|
||||
|
||||
# only allow None line_freqs with 'spectrum_fit' mode
|
||||
assert_raises(ValueError, notch_filter, a, sfreq, None, 'fft')
|
||||
assert_raises(ValueError, notch_filter, a, sfreq, None, 'iir')
|
||||
pytest.raises(ValueError, notch_filter, a, sfreq, None, 'fft')
|
||||
pytest.raises(ValueError, notch_filter, a, sfreq, None, 'iir')
|
||||
methods = ['spectrum_fit', 'spectrum_fit', 'fft', 'fft', 'iir']
|
||||
filter_lengths = ['auto', 'auto', 'auto', 8192, 'auto']
|
||||
line_freqs = [None, freqs, freqs, freqs, freqs]
|
||||
@@ -236,8 +242,8 @@ def test_resample():
|
||||
"""Test resampling."""
|
||||
x = rng.normal(0, 1, (10, 10, 10))
|
||||
x_rs = resample(x, 1, 2, 10)
|
||||
assert_equal(x.shape, (10, 10, 10))
|
||||
assert_equal(x_rs.shape, (10, 10, 5))
|
||||
assert x.shape == (10, 10, 10)
|
||||
assert x_rs.shape == (10, 10, 5)
|
||||
|
||||
x_2 = x.swapaxes(0, 1)
|
||||
x_2_rs = resample(x_2, 1, 2, 10)
|
||||
@@ -276,7 +282,7 @@ def test_resample_stim_channel():
|
||||
for new_data_len in (52598, 52599, 52600, 52601, 315599, 315600):
|
||||
new_data = _resample_stim_channels(data_chunk, new_data_len,
|
||||
data_chunk.shape[1])
|
||||
assert_equal(new_data.shape[1], new_data_len)
|
||||
assert new_data.shape[1] == new_data_len
|
||||
|
||||
|
||||
@requires_version('scipy', '0.16')
|
||||
@@ -290,33 +296,31 @@ def test_filters():
|
||||
|
||||
# let's test our catchers
|
||||
for fl in ['blah', [0, 1], 1000.5, '10ss', '10']:
|
||||
assert_raises(ValueError, filter_data, a, sfreq, 4, 8, None, fl,
|
||||
pytest.raises(ValueError, filter_data, a, sfreq, 4, 8, None, fl,
|
||||
1.0, 1.0, fir_design='firwin')
|
||||
for nj in ['blah', 0.5]:
|
||||
assert_raises(ValueError, filter_data, a, sfreq, 4, 8, None, 1000,
|
||||
pytest.raises(ValueError, filter_data, a, sfreq, 4, 8, None, 1000,
|
||||
1.0, 1.0, n_jobs=nj, phase='zero', fir_design='firwin')
|
||||
assert_raises(ValueError, filter_data, a, sfreq, 4, 8, None, 100,
|
||||
pytest.raises(ValueError, filter_data, a, sfreq, 4, 8, None, 100,
|
||||
1., 1., fir_window='foo')
|
||||
assert_raises(ValueError, filter_data, a, sfreq, 4, 8, None, 10,
|
||||
pytest.raises(ValueError, filter_data, a, sfreq, 4, 8, None, 10,
|
||||
1., 1., fir_design='firwin') # too short
|
||||
# > Nyq/2
|
||||
assert_raises(ValueError, filter_data, a, sfreq, 4, sfreq / 2., None,
|
||||
pytest.raises(ValueError, filter_data, a, sfreq, 4, sfreq / 2., None,
|
||||
100, 1.0, 1.0, fir_design='firwin')
|
||||
assert_raises(ValueError, filter_data, a, sfreq, -1, None, None,
|
||||
pytest.raises(ValueError, filter_data, a, sfreq, -1, None, None,
|
||||
100, 1.0, 1.0, fir_design='firwin')
|
||||
# these should work
|
||||
create_filter(a, sfreq, None, None, fir_design='firwin')
|
||||
create_filter(a, sfreq, None, None, method='iir')
|
||||
|
||||
# check our short-filter warning:
|
||||
with warnings.catch_warnings(record=True) as w:
|
||||
with pytest.warns(RuntimeWarning, match='attenuation'):
|
||||
# Warning for low attenuation
|
||||
filter_data(a, sfreq, 1, 8, filter_length=256, fir_design='firwin2')
|
||||
assert_true(any('attenuation' in str(ww.message) for ww in w))
|
||||
with warnings.catch_warnings(record=True) as w:
|
||||
with pytest.warns(RuntimeWarning, match='Increase filter_length'):
|
||||
# Warning for too short a filter
|
||||
filter_data(a, sfreq, 1, 8, filter_length='0.5s', fir_design='firwin2')
|
||||
assert_true(any('Increase filter_length' in str(ww.message) for ww in w))
|
||||
|
||||
# try new default and old default
|
||||
freqs = fftfreq(a.shape[-1], 1. / sfreq)
|
||||
@@ -376,19 +380,19 @@ def test_filters():
|
||||
iir_params = dict(ftype='cheby1', gpass=1, gstop=20, output='ba')
|
||||
iir_params = construct_iir_filter(iir_params, 40, 80, 1000, 'low')
|
||||
# this should be a third order filter
|
||||
assert_equal(iir_params['a'].size - 1, 3)
|
||||
assert_equal(iir_params['b'].size - 1, 3)
|
||||
assert iir_params['a'].size - 1 == 3
|
||||
assert iir_params['b'].size - 1 == 3
|
||||
iir_params = dict(ftype='butter', order=4, output='ba')
|
||||
iir_params = construct_iir_filter(iir_params, 40, None, 1000, 'low')
|
||||
assert_equal(iir_params['a'].size - 1, 4)
|
||||
assert_equal(iir_params['b'].size - 1, 4)
|
||||
iir_params = dict(ftype='cheby1', gpass=1, gstop=20, output='sos')
|
||||
assert iir_params['a'].size - 1 == 4
|
||||
assert iir_params['b'].size - 1 == 4
|
||||
iir_params = dict(ftype='cheby1', gpass=1, gstop=20)
|
||||
iir_params = construct_iir_filter(iir_params, 40, 80, 1000, 'low')
|
||||
# this should be a third order filter, which requires 2 SOS ((2, 6))
|
||||
assert_equal(iir_params['sos'].shape, (2, 6))
|
||||
assert iir_params['sos'].shape == (2, 6)
|
||||
iir_params = dict(ftype='butter', order=4, output='sos')
|
||||
iir_params = construct_iir_filter(iir_params, 40, None, 1000, 'low')
|
||||
assert_equal(iir_params['sos'].shape, (2, 6))
|
||||
assert iir_params['sos'].shape == (2, 6)
|
||||
|
||||
# check that picks work for 3d array with one channel and picks=[0]
|
||||
a = rng.randn(5 * sfreq, 5 * sfreq)
|
||||
@@ -404,7 +408,7 @@ def test_filters():
|
||||
# check for n-dimensional case
|
||||
a = rng.randn(2, 2, 2, 2)
|
||||
with warnings.catch_warnings(record=True): # filter too long
|
||||
assert_raises(ValueError, filter_data, a, sfreq, 4, 8,
|
||||
pytest.raises(ValueError, filter_data, a, sfreq, 4, 8,
|
||||
np.array([0, 1]), 100, 1.0, 1.0)
|
||||
|
||||
# check corner case (#4693)
|
||||
@@ -447,9 +451,9 @@ def test_filter_auto():
|
||||
assert_array_equal(x, x_filt)
|
||||
|
||||
# degenerate conditions
|
||||
assert_raises(ValueError, filter_data, x, -sfreq, 1, 10)
|
||||
assert_raises(ValueError, filter_data, x, sfreq, 1, sfreq * 0.75)
|
||||
assert_raises(TypeError, filter_data, x.astype(np.float32), sfreq, None,
|
||||
pytest.raises(ValueError, filter_data, x, -sfreq, 1, 10)
|
||||
pytest.raises(ValueError, filter_data, x, sfreq, 1, sfreq * 0.75)
|
||||
pytest.raises(TypeError, filter_data, x.astype(np.float32), sfreq, None,
|
||||
10, filter_length='auto', h_trans_bandwidth='auto', **kwargs)
|
||||
|
||||
|
||||
@@ -491,8 +495,7 @@ def test_cuda():
|
||||
# triage based on whether or not we actually expected to use CUDA
|
||||
from mne.cuda import _cuda_capable # allow above funs to set it
|
||||
tot = 12 if _cuda_capable else 0
|
||||
assert_true(sum(['Using CUDA for FFT FIR filtering' in o
|
||||
for o in out]) == tot)
|
||||
assert sum(['Using CUDA for FFT FIR filtering' in o for o in out]) == tot
|
||||
|
||||
# check resampling
|
||||
for window in ('boxcar', 'triang'):
|
||||
|
||||
+34
-27
@@ -1,5 +1,4 @@
|
||||
import os.path as op
|
||||
from nose.tools import assert_true, assert_raises
|
||||
import warnings
|
||||
|
||||
import numpy as np
|
||||
@@ -62,7 +61,7 @@ def test_bad_proj():
|
||||
_check_warnings(raw, events, count=0)
|
||||
|
||||
raw = read_raw_fif(raw_fname)
|
||||
assert_raises(ValueError, raw.del_proj, 'foo')
|
||||
pytest.raises(ValueError, raw.del_proj, 'foo')
|
||||
n_proj = len(raw.info['projs'])
|
||||
raw.del_proj(0)
|
||||
assert_equal(len(raw.info['projs']), n_proj - 1)
|
||||
@@ -97,7 +96,7 @@ def _check_warnings(raw, events, picks=None, count=3):
|
||||
-0.2, 0.5, picks=picks, preload=True, proj=True)
|
||||
assert_equal(len(w), count)
|
||||
for ww in w:
|
||||
assert_true('dangerous' in str(ww.message))
|
||||
assert 'dangerous' in str(ww.message)
|
||||
|
||||
|
||||
@testing.requires_testing_data
|
||||
@@ -115,7 +114,7 @@ def test_sensitivity_maps():
|
||||
stc = sensitivity_map(fwd, projs=None, ch_type=ch_type,
|
||||
mode='free', exclude='bads')
|
||||
assert_array_almost_equal(stc.data, w, decim)
|
||||
assert_true(stc.subject == 'sample')
|
||||
assert stc.subject == 'sample'
|
||||
# let's just make sure the others run
|
||||
if ch_type == 'grad':
|
||||
# fixed (2)
|
||||
@@ -143,8 +142,8 @@ def test_sensitivity_maps():
|
||||
stc = sensitivity_map(fwd, projs=[make_eeg_average_ref_proj(fwd['info'])],
|
||||
ch_type='eeg', exclude='bads')
|
||||
# test corner case for projs being passed but no valid ones (#3135)
|
||||
assert_raises(ValueError, sensitivity_map, fwd, projs=None, mode='angle')
|
||||
assert_raises(RuntimeError, sensitivity_map, fwd, projs=[], mode='angle')
|
||||
pytest.raises(ValueError, sensitivity_map, fwd, projs=None, mode='angle')
|
||||
pytest.raises(RuntimeError, sensitivity_map, fwd, projs=[], mode='angle')
|
||||
# test volume source space
|
||||
fname = op.join(sample_path, 'sample_audvis_trunc-meg-vol-7-fwd.fif')
|
||||
fwd = mne.read_forward_solution(fname)
|
||||
@@ -171,12 +170,12 @@ def test_compute_proj_epochs():
|
||||
op.join(tempdir, 'test-proj.fif.gz')]:
|
||||
projs2 = read_proj(p_fname)
|
||||
|
||||
assert_true(len(projs) == len(projs2))
|
||||
assert len(projs) == len(projs2)
|
||||
|
||||
for p1, p2 in zip(projs, projs2):
|
||||
assert_true(p1['desc'] == p2['desc'])
|
||||
assert_true(p1['data']['col_names'] == p2['data']['col_names'])
|
||||
assert_true(p1['active'] == p2['active'])
|
||||
assert p1['desc'] == p2['desc']
|
||||
assert p1['data']['col_names'] == p2['data']['col_names']
|
||||
assert p1['active'] == p2['active']
|
||||
# compare with sign invariance
|
||||
p1_data = p1['data']['data'] * np.sign(p1['data']['data'][0, 0])
|
||||
p2_data = p2['data']['data'] * np.sign(p2['data']['data'][0, 0])
|
||||
@@ -196,8 +195,8 @@ def test_compute_proj_epochs():
|
||||
projs = activate_proj(projs)
|
||||
proj, nproj, U = make_projector(projs, epochs.ch_names, bads=[])
|
||||
|
||||
assert_true(nproj == 2)
|
||||
assert_true(U.shape[1] == 2)
|
||||
assert nproj == 2
|
||||
assert U.shape[1] == 2
|
||||
|
||||
# test that you can save them
|
||||
epochs.info['projs'] += projs
|
||||
@@ -207,13 +206,13 @@ def test_compute_proj_epochs():
|
||||
projs = read_proj(proj_fname)
|
||||
|
||||
projs_evoked = compute_proj_evoked(evoked, n_grad=1, n_mag=1, n_eeg=0)
|
||||
assert_true(len(projs_evoked) == 2)
|
||||
assert len(projs_evoked) == 2
|
||||
# XXX : test something
|
||||
|
||||
# test parallelization
|
||||
projs = compute_proj_epochs(epochs, n_grad=1, n_mag=1, n_eeg=0, n_jobs=1,
|
||||
desc_prefix='foobar')
|
||||
assert_true(all('foobar' in x['desc'] for x in projs))
|
||||
assert all('foobar' in x['desc'] for x in projs)
|
||||
projs = activate_proj(projs)
|
||||
proj_par, _, _ = make_projector(projs, epochs.ch_names, bads=[])
|
||||
assert_allclose(proj, proj_par, rtol=1e-8, atol=1e-16)
|
||||
@@ -240,14 +239,14 @@ def test_compute_proj_raw():
|
||||
warnings.simplefilter('always')
|
||||
projs = compute_proj_raw(raw, duration=ii - 0.1, stop=raw_time,
|
||||
n_grad=1, n_mag=1, n_eeg=0)
|
||||
assert_true(len(w) == 1)
|
||||
assert len(w) == 1
|
||||
|
||||
# test that you can compute the projection matrix
|
||||
projs = activate_proj(projs)
|
||||
proj, nproj, U = make_projector(projs, raw.ch_names, bads=[])
|
||||
|
||||
assert_true(nproj == 2)
|
||||
assert_true(U.shape[1] == 2)
|
||||
assert nproj == 2
|
||||
assert U.shape[1] == 2
|
||||
|
||||
# test that you can save them
|
||||
raw.info['projs'] += projs
|
||||
@@ -264,8 +263,8 @@ def test_compute_proj_raw():
|
||||
projs = activate_proj(projs)
|
||||
proj, nproj, U = make_projector(projs, raw.ch_names, bads=[])
|
||||
|
||||
assert_true(nproj == 2)
|
||||
assert_true(U.shape[1] == 2)
|
||||
assert nproj == 2
|
||||
assert U.shape[1] == 2
|
||||
|
||||
# test that you can save them
|
||||
raw.info['projs'] += projs
|
||||
@@ -301,7 +300,7 @@ def test_make_eeg_average_ref_proj():
|
||||
eeg = mne.pick_types(raw.info, meg=False, eeg=True)
|
||||
|
||||
# No average EEG reference
|
||||
assert_true(not np.all(raw._data[eeg].mean(axis=0) < 1e-19))
|
||||
assert not np.all(raw._data[eeg].mean(axis=0) < 1e-19)
|
||||
|
||||
# Apply average EEG reference
|
||||
car = make_eeg_average_ref_proj(raw.info)
|
||||
@@ -312,36 +311,44 @@ def test_make_eeg_average_ref_proj():
|
||||
|
||||
# Error when custom reference has already been applied
|
||||
raw.info['custom_ref_applied'] = True
|
||||
assert_raises(RuntimeError, make_eeg_average_ref_proj, raw.info)
|
||||
pytest.raises(RuntimeError, make_eeg_average_ref_proj, raw.info)
|
||||
|
||||
# test that an average EEG ref is not added when doing proj
|
||||
raw.set_eeg_reference(projection=True)
|
||||
assert _has_eeg_average_ref_proj(raw.info['projs'])
|
||||
raw.del_proj(idx=-1)
|
||||
assert not _has_eeg_average_ref_proj(raw.info['projs'])
|
||||
raw.apply_proj()
|
||||
assert not _has_eeg_average_ref_proj(raw.info['projs'])
|
||||
|
||||
|
||||
def test_has_eeg_average_ref_proj():
|
||||
"""Test checking whether an EEG average reference exists"""
|
||||
assert_true(not _has_eeg_average_ref_proj([]))
|
||||
assert not _has_eeg_average_ref_proj([])
|
||||
|
||||
raw = read_raw_fif(raw_fname)
|
||||
raw.set_eeg_reference(projection=True)
|
||||
assert_true(_has_eeg_average_ref_proj(raw.info['projs']))
|
||||
assert _has_eeg_average_ref_proj(raw.info['projs'])
|
||||
|
||||
|
||||
def test_needs_eeg_average_ref_proj():
|
||||
"""Test checking whether a recording needs an EEG average reference"""
|
||||
raw = read_raw_fif(raw_fname)
|
||||
assert_true(_needs_eeg_average_ref_proj(raw.info))
|
||||
assert _needs_eeg_average_ref_proj(raw.info)
|
||||
|
||||
raw.set_eeg_reference(projection=True)
|
||||
assert_true(not _needs_eeg_average_ref_proj(raw.info))
|
||||
assert not _needs_eeg_average_ref_proj(raw.info)
|
||||
|
||||
# No EEG channels
|
||||
raw = read_raw_fif(raw_fname, preload=True)
|
||||
eeg = [raw.ch_names[c] for c in pick_types(raw.info, meg=False, eeg=True)]
|
||||
raw.drop_channels(eeg)
|
||||
assert_true(not _needs_eeg_average_ref_proj(raw.info))
|
||||
assert not _needs_eeg_average_ref_proj(raw.info)
|
||||
|
||||
# Custom ref flag set
|
||||
raw = read_raw_fif(raw_fname)
|
||||
raw.info['custom_ref_applied'] = True
|
||||
assert_true(not _needs_eeg_average_ref_proj(raw.info))
|
||||
assert not _needs_eeg_average_ref_proj(raw.info)
|
||||
|
||||
|
||||
run_tests_if_main()
|
||||
|
||||
@@ -148,12 +148,12 @@ def test_volume_stc():
|
||||
with warnings.catch_warnings(record=True): # nib<->numpy
|
||||
img = nib.load(vol_fname)
|
||||
assert_true(img.shape == t1_img.shape + (len(stc.times),))
|
||||
assert_array_almost_equal(img.affine, t1_img.affine, decimal=5)
|
||||
assert_allclose(img.affine, t1_img.affine, atol=1e-5)
|
||||
|
||||
# export without saving
|
||||
img = stc.as_volume(src, dest='mri', mri_resolution=True)
|
||||
assert_true(img.shape == t1_img.shape + (len(stc.times),))
|
||||
assert_array_almost_equal(img.affine, t1_img.affine, decimal=5)
|
||||
assert_allclose(img.affine, t1_img.affine, atol=1e-5)
|
||||
|
||||
except ImportError:
|
||||
print('Save as nifti test skipped, needs NiBabel')
|
||||
|
||||
@@ -7,9 +7,9 @@ from copy import deepcopy
|
||||
import math
|
||||
import numpy as np
|
||||
from scipy import fftpack
|
||||
# XXX explore cuda optimazation at some point.
|
||||
# XXX explore cuda optimization at some point.
|
||||
|
||||
from ..io.pick import pick_types, pick_info
|
||||
from ..io.pick import _pick_data_channels, pick_info
|
||||
from ..utils import verbose, warn
|
||||
from ..parallel import parallel_func, check_n_jobs
|
||||
from .tfr import AverageTFR, _get_data
|
||||
@@ -252,7 +252,7 @@ def tfr_stockwell(inst, fmin=None, fmax=None, n_fft=None,
|
||||
"""
|
||||
# verbose dec is used b/c subfunctions are verbose
|
||||
data = _get_data(inst, return_itc)
|
||||
picks = pick_types(inst.info, meg=True, eeg=True)
|
||||
picks = _pick_data_channels(inst.info)
|
||||
info = pick_info(inst.info, picks)
|
||||
data = data[:, picks, :]
|
||||
n_jobs = check_n_jobs(n_jobs)
|
||||
|
||||
@@ -1140,6 +1140,7 @@ def csd_array_morlet(X, sfreq, frequencies, t0=0, tmin=None, tmax=None,
|
||||
csd_tstart = None if tmin is None else np.searchsorted(times, tmin - 1e-10)
|
||||
csd_tstop = None if tmax is None else np.searchsorted(times, tmax + 1e-10)
|
||||
csd_tslice = slice(csd_tstart, csd_tstop)
|
||||
times = times[csd_tslice]
|
||||
|
||||
# Compute the CSD
|
||||
return _execute_csd_function(X, times, frequencies, _csd_morlet,
|
||||
|
||||
@@ -412,6 +412,10 @@ def test_csd_fourier():
|
||||
else:
|
||||
csd = csd_fourier(epochs, fmin=9, fmax=23, tmin=tmin, tmax=tmax)
|
||||
|
||||
if tmin is None and tmax is None:
|
||||
assert csd.tmin == 0 and csd.tmax == 9.98
|
||||
else:
|
||||
assert csd.tmin == tmin and csd.tmax == tmax
|
||||
csd = csd.mean([9.9, 14.9, 21.9], [10.1, 15.1, 22.1])
|
||||
_test_csd_matrix(csd)
|
||||
|
||||
@@ -457,6 +461,10 @@ def test_csd_multitaper():
|
||||
else:
|
||||
csd = csd_multitaper(epochs, adaptive=adaptive, fmin=9, fmax=23,
|
||||
tmin=tmin, tmax=tmax)
|
||||
if tmin is None and tmax is None:
|
||||
assert csd.tmin == 0 and csd.tmax == 9.98
|
||||
else:
|
||||
assert csd.tmin == tmin and csd.tmax == tmax
|
||||
csd = csd.mean([9.9, 14.9, 21.9], [10.1, 15.1, 22.1])
|
||||
_test_csd_matrix(csd)
|
||||
|
||||
@@ -510,6 +518,10 @@ def test_csd_morlet():
|
||||
else:
|
||||
csd = csd_morlet(epochs, frequencies=freqs, n_cycles=n_cycles,
|
||||
tmin=tmin, tmax=tmax)
|
||||
if tmin is None and tmax is None:
|
||||
assert csd.tmin == 0 and csd.tmax == 9.98
|
||||
else:
|
||||
assert csd.tmin == tmin and csd.tmax == tmax
|
||||
_test_csd_matrix(csd)
|
||||
|
||||
# CSD diagonals should contain PSD
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import numpy as np
|
||||
from scipy import linalg
|
||||
from numpy.testing import assert_almost_equal, assert_array_almost_equal
|
||||
from nose.tools import assert_true
|
||||
|
||||
from mne.time_frequency.stft import stft, istft, stftfreq, stft_norm2
|
||||
|
||||
@@ -10,7 +9,7 @@ def test_stft():
|
||||
"Test stft and istft tight frame property"
|
||||
sfreq = 1000. # Hz
|
||||
f = 7. # Hz
|
||||
for T in [253, 256]: # try with even and odd numbers
|
||||
for T in [127, 128]: # try with even and odd numbers
|
||||
# Test with low frequency signal
|
||||
t = np.arange(T).astype(np.float)
|
||||
x = np.sin(2 * np.pi * f * t / sfreq)
|
||||
@@ -24,9 +23,9 @@ def test_stft():
|
||||
|
||||
max_freq = freqs[np.argmax(np.sum(np.abs(X[0]) ** 2, axis=1))]
|
||||
|
||||
assert_true(X.shape[1] == len(freqs))
|
||||
assert_true(np.all(freqs >= 0.))
|
||||
assert_true(np.abs(max_freq - f) < 1.)
|
||||
assert X.shape[1] == len(freqs)
|
||||
assert np.all(freqs >= 0.)
|
||||
assert np.abs(max_freq - f) < 1.
|
||||
assert_array_almost_equal(x, xp, decimal=6)
|
||||
|
||||
# norm conservation thanks to tight frame property
|
||||
@@ -44,8 +43,8 @@ def test_stft():
|
||||
|
||||
max_freq = freqs[np.argmax(np.sum(np.abs(X[0]) ** 2, axis=1))]
|
||||
|
||||
assert_true(X.shape[1] == len(freqs))
|
||||
assert_true(np.all(freqs >= 0.))
|
||||
assert X.shape[1] == len(freqs)
|
||||
assert np.all(freqs >= 0.)
|
||||
assert_array_almost_equal(x, xp, decimal=6)
|
||||
|
||||
# norm conservation thanks to tight frame property
|
||||
@@ -57,4 +56,4 @@ def test_stft():
|
||||
x = np.zeros((0, T))
|
||||
X = stft(x, wsize, tstep)
|
||||
xp = istft(X, tstep, T)
|
||||
assert_true(xp.shape == x.shape)
|
||||
assert xp.shape == x.shape
|
||||
|
||||
@@ -12,7 +12,7 @@ from numpy.testing import assert_array_almost_equal, assert_allclose
|
||||
|
||||
from scipy import fftpack
|
||||
|
||||
from mne import read_events, Epochs
|
||||
from mne import read_events, Epochs, make_fixed_length_events
|
||||
from mne.io import read_raw_fif
|
||||
from mne.time_frequency._stockwell import (tfr_stockwell, _st,
|
||||
_precompute_st_windows,
|
||||
@@ -24,6 +24,17 @@ from mne.utils import run_tests_if_main
|
||||
|
||||
base_dir = op.join(op.dirname(__file__), '..', '..', 'io', 'tests', 'data')
|
||||
raw_fname = op.join(base_dir, 'test_raw.fif')
|
||||
raw_ctf_fname = op.join(base_dir, 'test_ctf_raw.fif')
|
||||
|
||||
|
||||
def test_stockwell_ctf():
|
||||
"""Test that Stockwell can be calculated on CTF data."""
|
||||
raw = read_raw_fif(raw_ctf_fname)
|
||||
raw.apply_gradient_compensation(3)
|
||||
events = make_fixed_length_events(raw, duration=0.5)
|
||||
evoked = Epochs(raw, events, tmin=-0.2, tmax=0.3, decim=10,
|
||||
preload=True, verbose='error').average()
|
||||
tfr_stockwell(evoked, verbose='error') # smoke test
|
||||
|
||||
|
||||
def test_stockwell_check_input():
|
||||
|
||||
@@ -20,10 +20,20 @@ from itertools import product
|
||||
import matplotlib
|
||||
matplotlib.use('Agg') # for testing don't use X server
|
||||
|
||||
raw_fname = op.join(op.dirname(__file__), '..', '..', 'io', 'tests', 'data',
|
||||
'test_raw.fif')
|
||||
event_fname = op.join(op.dirname(__file__), '..', '..', 'io', 'tests',
|
||||
'data', 'test-eve.fif')
|
||||
data_path = op.join(op.dirname(__file__), '..', '..', 'io', 'tests', 'data')
|
||||
raw_fname = op.join(data_path, 'test_raw.fif')
|
||||
event_fname = op.join(data_path, 'test-eve.fif')
|
||||
raw_ctf_fname = op.join(data_path, 'test_ctf_raw.fif')
|
||||
|
||||
|
||||
def test_tfr_ctf():
|
||||
"""Test that TFRs can be calculated on CTF data."""
|
||||
raw = read_raw_fif(raw_ctf_fname).crop(0, 1)
|
||||
raw.apply_gradient_compensation(3)
|
||||
events = mne.make_fixed_length_events(raw, duration=0.5)
|
||||
epochs = mne.Epochs(raw, events)
|
||||
for method in (tfr_multitaper, tfr_morlet):
|
||||
method(epochs, [10], 1) # smoke test
|
||||
|
||||
|
||||
def test_morlet():
|
||||
|
||||
@@ -23,7 +23,7 @@ from ..parallel import parallel_func
|
||||
from ..utils import logger, verbose, _time_mask, check_fname, sizeof_fmt
|
||||
from ..channels.channels import ContainsMixin, UpdateChannelsMixin
|
||||
from ..channels.layout import _pair_grad_sensors
|
||||
from ..io.pick import (pick_info, pick_types, _pick_data_channels,
|
||||
from ..io.pick import (pick_info, _pick_data_channels,
|
||||
channel_type, _pick_inst, _get_channel_types)
|
||||
from ..io.meas_info import Info
|
||||
from ..utils import SizeMixin
|
||||
@@ -668,7 +668,7 @@ def tfr_morlet(inst, freqs, n_cycles, use_fft=False, return_itc=True, decim=1,
|
||||
The number of jobs to run in parallel.
|
||||
picks : array-like of int | None, defaults to None
|
||||
The indices of the channels to decompose. If None, all available
|
||||
channels are decomposed.
|
||||
good data channels are decomposed.
|
||||
zero_mean : bool, defaults to True
|
||||
Make sure the wavelet has a mean of zero.
|
||||
|
||||
@@ -825,7 +825,7 @@ def tfr_multitaper(inst, freqs, n_cycles, time_bandwidth=4.0,
|
||||
The number of jobs to run in parallel.
|
||||
picks : array-like of int | None, defaults to None
|
||||
The indices of the channels to decompose. If None, all available
|
||||
channels are decomposed.
|
||||
good data channels are decomposed.
|
||||
average : bool, defaults to True
|
||||
If True average across Epochs.
|
||||
|
||||
@@ -2092,8 +2092,7 @@ def _get_data(inst, return_itc):
|
||||
def _prepare_picks(info, data, picks):
|
||||
"""Prepare the picks."""
|
||||
if picks is None:
|
||||
picks = pick_types(info, meg=True, eeg=True, ref_meg=False,
|
||||
exclude='bads')
|
||||
picks = _pick_data_channels(info, with_ref_meg=True, exclude='bads')
|
||||
if np.array_equal(picks, np.arange(len(data))):
|
||||
picks = slice(None)
|
||||
else:
|
||||
|
||||
+17
-13
@@ -1245,7 +1245,10 @@ def _limits_to_control_points(clim, stc_data, colormap, transparent,
|
||||
# Based on type of limits specified, get cmap control points
|
||||
if colormap == 'auto':
|
||||
if clim == 'auto':
|
||||
colormap = 'mne' if (stc_data < 0).any() else 'hot'
|
||||
if allow_pos_lims and (stc_data < 0).any():
|
||||
colormap = 'mne'
|
||||
else:
|
||||
colormap = 'hot'
|
||||
else:
|
||||
if 'lims' in clim:
|
||||
colormap = 'hot'
|
||||
@@ -1256,11 +1259,12 @@ def _limits_to_control_points(clim, stc_data, colormap, transparent,
|
||||
ctrl_pts = np.percentile(np.abs(stc_data), [96, 97.5, 99.95])
|
||||
elif isinstance(clim, dict):
|
||||
# Get appropriate key for clim if it's a dict
|
||||
limit_key = ['lims', 'pos_lims'][colormap in ('mne', 'mne_analyze')]
|
||||
if colormap != 'auto' and limit_key not in clim.keys():
|
||||
raise KeyError('"pos_lims" must be used with "mne" colormap')
|
||||
if 'pos_lims' in clim and not allow_pos_lims:
|
||||
raise ValueError('Cannot use pos_lims for clim')
|
||||
raise ValueError('Cannot use "pos_lims" for clim, use "lims" '
|
||||
'instead')
|
||||
limit_key = ['lims', 'pos_lims'][colormap in ('mne', 'mne_analyze')]
|
||||
if limit_key not in clim.keys():
|
||||
raise KeyError('"pos_lims" must be used with "mne" colormap')
|
||||
clim['kind'] = clim.get('kind', 'percent')
|
||||
if clim['kind'] == 'percent':
|
||||
ctrl_pts = np.percentile(np.abs(stc_data),
|
||||
@@ -1490,7 +1494,7 @@ def _plot_mpl_stc(stc, subject=None, surface='inflated', hemi='lh',
|
||||
|
||||
|
||||
def plot_source_estimates(stc, subject=None, surface='inflated', hemi='lh',
|
||||
colormap='hot', time_label='auto',
|
||||
colormap='auto', time_label='auto',
|
||||
smoothing_steps=10, transparent=None, alpha=1.0,
|
||||
time_viewer=False, subjects_dir=None, figure=None,
|
||||
views='lat', colorbar=True, clim='auto',
|
||||
@@ -1662,7 +1666,7 @@ def plot_source_estimates(stc, subject=None, surface='inflated', hemi='lh',
|
||||
|
||||
title = subject if len(hemis) > 1 else '%s - %s' % (subject, hemis[0])
|
||||
with warnings.catch_warnings(record=True): # traits warnings
|
||||
brain = Brain(subject, hemi=hemi, surf=surface, curv=True,
|
||||
brain = Brain(subject, hemi=hemi, surf=surface,
|
||||
title=title, cortex=cortex, size=size,
|
||||
background=background, foreground=foreground,
|
||||
figure=figure, subjects_dir=subjects_dir,
|
||||
@@ -1715,7 +1719,7 @@ def _get_ps_kwargs(initial_time, require='0.6'):
|
||||
return initial_time, ad_kwargs, sd_kwargs
|
||||
|
||||
|
||||
def plot_vector_source_estimates(stc, subject=None, hemi='lh', colormap='auto',
|
||||
def plot_vector_source_estimates(stc, subject=None, hemi='lh', colormap='hot',
|
||||
time_label='auto', smoothing_steps=10,
|
||||
transparent=None, brain_alpha=0.4,
|
||||
overlay_alpha=None, vector_alpha=1.0,
|
||||
@@ -1861,7 +1865,7 @@ def plot_vector_source_estimates(stc, subject=None, hemi='lh', colormap='auto',
|
||||
|
||||
title = subject if len(hemis) > 1 else '%s - %s' % (subject, hemis[0])
|
||||
with warnings.catch_warnings(record=True): # traits warnings
|
||||
brain = Brain(subject, hemi=hemi, surf='white', curv=True,
|
||||
brain = Brain(subject, hemi=hemi, surf='white',
|
||||
title=title, cortex=cortex, size=size,
|
||||
background=background, foreground=foreground,
|
||||
figure=figure, subjects_dir=subjects_dir,
|
||||
@@ -2398,15 +2402,15 @@ def _plot_dipole(ax, data, points, idx, dipole, gridx, gridy, ori, coord_frame,
|
||||
colors[idx] = 'r'
|
||||
size = np.repeat(5, len(points))
|
||||
size[idx] = 20
|
||||
visibles = range(len(points))
|
||||
visible = np.arange(len(points))
|
||||
else:
|
||||
colors = 'r'
|
||||
size = 20
|
||||
visibles = idx
|
||||
visible = idx
|
||||
|
||||
offset = np.min(gridx)
|
||||
ax.scatter(xs=xyz[visibles, 0], ys=xyz[visibles, 1],
|
||||
zs=xyz[visibles, 2], zorder=2, s=size, facecolor=colors)
|
||||
ax.scatter(xs=xyz[visible, 0], ys=xyz[visible, 1],
|
||||
zs=xyz[visible, 2], zorder=2, s=size, facecolor=colors)
|
||||
xx = np.linspace(offset, xyz[idx, 0], xidx)
|
||||
yy = np.linspace(offset, xyz[idx, 1], yidx)
|
||||
zz = np.linspace(offset, xyz[idx, 2], zidx)
|
||||
|
||||
+8
-7
@@ -79,7 +79,7 @@ def _butterfly_on_button_press(event, params):
|
||||
|
||||
|
||||
def _line_plot_onselect(xmin, xmax, ch_types, info, data, times, text=None,
|
||||
psd=False):
|
||||
psd=False, time_unit='s'):
|
||||
"""Draw topomaps from the selected area."""
|
||||
import matplotlib.pyplot as plt
|
||||
ch_types = [type_ for type_ in ch_types if type_ in ('eeg', 'grad', 'mag')]
|
||||
@@ -133,7 +133,7 @@ def _line_plot_onselect(xmin, xmax, ch_types, info, data, times, text=None,
|
||||
plot_topomap(this_data, pos, cmap=cmap, vmin=vmin, vmax=vmax,
|
||||
axes=axarr[0][idx], show=False)
|
||||
|
||||
unit = 'Hz' if psd else 'ms'
|
||||
unit = 'Hz' if psd else time_unit
|
||||
fig.suptitle('Average over %.2f%s - %.2f%s' % (xmin, unit, xmax, unit),
|
||||
y=0.1)
|
||||
tight_layout(pad=2.0, fig=fig)
|
||||
@@ -273,7 +273,8 @@ def _plot_evoked(evoked, picks, exclude, unit, show, ylim, proj, xlim, hline,
|
||||
_plot_lines(evoked.data, info, picks, fig, axes, spatial_colors, unit,
|
||||
units, scalings, hline, gfp, types, zorder, xlim, ylim,
|
||||
times, bad_ch_idx, titles, ch_types_used, selectable,
|
||||
False, line_alpha=1., nave=evoked.nave)
|
||||
False, line_alpha=1., nave=evoked.nave,
|
||||
time_unit=time_unit)
|
||||
plt.setp(axes, xlabel='Time (%s)' % time_unit)
|
||||
|
||||
elif plot_type == 'image':
|
||||
@@ -305,7 +306,7 @@ def _plot_evoked(evoked, picks, exclude, unit, show, ylim, proj, xlim, hline,
|
||||
def _plot_lines(data, info, picks, fig, axes, spatial_colors, unit, units,
|
||||
scalings, hline, gfp, types, zorder, xlim, ylim, times,
|
||||
bad_ch_idx, titles, ch_types_used, selectable, psd,
|
||||
line_alpha, nave):
|
||||
line_alpha, nave, time_unit='ms'):
|
||||
"""Plot data as butterfly plot."""
|
||||
from matplotlib import patheffects, pyplot as plt
|
||||
from matplotlib.widgets import SpanSelector
|
||||
@@ -456,7 +457,7 @@ def _plot_lines(data, info, picks, fig, axes, spatial_colors, unit, units,
|
||||
callback_onselect = partial(_line_plot_onselect,
|
||||
ch_types=ch_types_used, info=info,
|
||||
data=data, times=times, text=text,
|
||||
psd=psd)
|
||||
psd=psd, time_unit=time_unit)
|
||||
blit = False if plt.get_backend() == 'MacOSX' else True
|
||||
minspan = 0 if len(times) < 2 else times[1] - times[0]
|
||||
ax._span_selector = SpanSelector(
|
||||
@@ -1280,7 +1281,7 @@ def plot_evoked_joint(evoked, times="peaks", title='', picks=None,
|
||||
# simply create a new evoked object with the desired channel selection
|
||||
evoked = _pick_inst(evoked, picks, exclude, copy=True)
|
||||
info = evoked.info
|
||||
ch_types = _get_channel_types(info)
|
||||
ch_types = _get_channel_types(info, restrict_data_types=True)
|
||||
|
||||
# if multiple sensor types: one plot per channel type, recursive call
|
||||
if len(ch_types) > 1:
|
||||
@@ -1812,7 +1813,7 @@ def plot_compare_evokeds(evokeds, picks=None, gfp=False, colors=None,
|
||||
elif picks is None:
|
||||
logger.info("No picks, plotting the GFP ...")
|
||||
gfp = True
|
||||
picks = _pick_data_channels(info)
|
||||
picks = _pick_data_channels(info, with_ref_meg=False)
|
||||
|
||||
if not isinstance(picks, (list, np.ndarray)):
|
||||
raise TypeError("picks should be a list or np.array of integers. "
|
||||
|
||||
+2
-2
@@ -612,9 +612,9 @@ def plot_ica_overlay(ica, inst, exclude=None, picks=None, start=None,
|
||||
times=times, title=title,
|
||||
ch_types_used=ch_types_used, show=show)
|
||||
elif isinstance(inst, Evoked):
|
||||
if start is not None and stop is not None:
|
||||
inst = inst.copy().crop(start, stop)
|
||||
inst = inst.copy().crop(start, stop)
|
||||
if picks is not None:
|
||||
inst.info['comps'] = [] # can be safely disabled
|
||||
inst.pick_channels([inst.ch_names[p] for p in picks])
|
||||
evoked_cln = ica.apply(inst.copy(), exclude=exclude)
|
||||
fig = _plot_ica_overlay_evoked(evoked=inst, evoked_cln=evoked_cln,
|
||||
|
||||
@@ -412,12 +412,14 @@ def test_plot_vec_source_estimates():
|
||||
data = np.random.RandomState(0).rand(n_verts, 3, n_time)
|
||||
stc = VectorSourceEstimate(data, vertices, 1, 1)
|
||||
|
||||
with warnings.catch_warnings(record=True):
|
||||
with warnings.catch_warnings(record=True) as w:
|
||||
warnings.simplefilter('always')
|
||||
stc.plot('sample', subjects_dir=subjects_dir)
|
||||
with pytest.raises(ValueError, match='use pos_lims'):
|
||||
|
||||
with pytest.raises(ValueError, match='use "pos_lims"'):
|
||||
stc.plot('sample', subjects_dir=subjects_dir,
|
||||
clim=dict(pos_lims=[1, 2, 3]))
|
||||
assert len(w) == 0
|
||||
|
||||
|
||||
run_tests_if_main()
|
||||
|
||||
@@ -16,6 +16,7 @@ from numpy.testing import assert_raises, assert_allclose
|
||||
from nose.tools import assert_true
|
||||
import pytest
|
||||
|
||||
import mne
|
||||
from mne import (read_events, Epochs, pick_types, read_cov, compute_covariance,
|
||||
make_fixed_length_events)
|
||||
from mne.channels import read_layout
|
||||
@@ -24,6 +25,7 @@ from mne.utils import run_tests_if_main, catch_logging
|
||||
from mne.viz.evoked import _line_plot_onselect, plot_compare_evokeds
|
||||
from mne.viz.utils import _fake_click
|
||||
from mne.stats import _parametric_ci
|
||||
from mne.datasets import testing
|
||||
|
||||
# Set our plotters to test mode
|
||||
import matplotlib
|
||||
@@ -305,4 +307,22 @@ def test_plot_evoked():
|
||||
assert_true('Need more than one' in log_file.getvalue())
|
||||
|
||||
|
||||
@testing.requires_testing_data
|
||||
def test_plot_ctf():
|
||||
"""Test plotting of CTF evoked."""
|
||||
ctf_dir = op.join(testing.data_path(download=False), 'CTF')
|
||||
raw_fname = op.join(ctf_dir, 'testdata_ctf.ds')
|
||||
|
||||
raw = mne.io.read_raw_ctf(raw_fname, preload=True)
|
||||
events = np.array([[200, 0, 1]])
|
||||
event_id = 1
|
||||
tmin, tmax = -0.1, 0.5 # start and end of an epoch in sec.
|
||||
picks = mne.pick_types(raw.info, meg=True, stim=True, eog=True,
|
||||
ref_meg=True, exclude='bads')
|
||||
epochs = mne.Epochs(raw, events, event_id, tmin, tmax, proj=True,
|
||||
picks=picks, preload=True)
|
||||
evoked = epochs.average()
|
||||
evoked.plot_joint(times=[0.1])
|
||||
mne.viz.plot_compare_evokeds([evoked, evoked])
|
||||
|
||||
run_tests_if_main()
|
||||
|
||||
@@ -28,6 +28,7 @@ raw_fname = op.join(base_dir, 'test_raw.fif')
|
||||
cov_fname = op.join(base_dir, 'test-cov.fif')
|
||||
event_name = op.join(base_dir, 'test-eve.fif')
|
||||
event_id, tmin, tmax = 1, -0.1, 0.2
|
||||
raw_ctf_fname = op.join(base_dir, 'test_ctf_raw.fif')
|
||||
|
||||
|
||||
def _get_raw(preload=False):
|
||||
@@ -248,6 +249,16 @@ def test_plot_ica_overlay():
|
||||
ica.plot_overlay(raw)
|
||||
plt.close('all')
|
||||
|
||||
# smoke test for CTF
|
||||
raw = read_raw_fif(raw_ctf_fname)
|
||||
raw.apply_gradient_compensation(3)
|
||||
picks = pick_types(raw.info, meg=True, ref_meg=False)
|
||||
ica = ICA(n_components=2, max_pca_components=3, n_pca_components=3)
|
||||
ica.fit(raw, picks=picks)
|
||||
ecg_epochs = create_ecg_epochs(raw)
|
||||
ica.plot_overlay(ecg_epochs.average())
|
||||
plt.close('all')
|
||||
|
||||
|
||||
@requires_sklearn
|
||||
def test_plot_ica_scores():
|
||||
|
||||
@@ -5,7 +5,7 @@ Artifact Correction with ICA
|
||||
ICA finds directions in the feature space
|
||||
corresponding to projections with high non-Gaussianity. We thus obtain
|
||||
a decomposition into independent components, and the artifact's contribution
|
||||
is localized in only a small number of components.
|
||||
is typically localized in only a small number of components.
|
||||
These components have to be correctly identified and removed.
|
||||
|
||||
If EOG or ECG recordings are available, they can be used in ICA to
|
||||
|
||||
@@ -736,7 +736,7 @@ def baseline_plot(x):
|
||||
baseline_plot(x)
|
||||
|
||||
###############################################################################
|
||||
# In respose, Maess *et al.* 2016 [11]_ note that these simulations do not
|
||||
# In response, Maess *et al.* 2016 [11]_ note that these simulations do not
|
||||
# address cases of pre-stimulus activity that is shared across conditions, as
|
||||
# applying baseline correction will effectively copy the topology outside the
|
||||
# baseline period. We can see this if we give our signal ``x`` with some
|
||||
|
||||
@@ -56,7 +56,7 @@ best_time = dip.times[best_idx]
|
||||
print('Highest GOF %0.1f%% at t=%0.1f ms with confidence volume %0.1f cm^3'
|
||||
% (dip.gof[best_idx], best_time * 1000,
|
||||
dip.conf['vol'][best_idx] * 100 ** 3))
|
||||
# rememeber to create a subplot for the colorbar
|
||||
# remember to create a subplot for the colorbar
|
||||
fig, axes = plt.subplots(nrows=1, ncols=4, figsize=[10., 3.4])
|
||||
vmin, vmax = -400, 400 # make sure each plot has same colour range
|
||||
|
||||
|
||||
@@ -38,7 +38,7 @@ What you can do with MNE Python
|
||||
- **Spectrum estimation** using multi-taper method
|
||||
- **Mixed Source Models** combining cortical and subcortical structures
|
||||
- **Dipole Fitting**
|
||||
- **Decoding** multivariate pattern analyis of M/EEG topographies
|
||||
- **Decoding** multivariate pattern analysis of M/EEG topographies
|
||||
- **Compute contrasts** between conditions, between sensors, across
|
||||
subjects etc.
|
||||
- **Non-parametric statistics** in time, space and frequency
|
||||
|
||||
Reference in New Issue
Block a user