Skip to content

Commit

Permalink
ENH: reorganize template modules consistently
Browse files Browse the repository at this point in the history
fix setup.py

edit manifest

fix attempt setup.py

more setup + py3k fixes

cleanup, add Fieldtrip credits, update reference and whats new

address suggestions from hangout

remove montages.py
  • Loading branch information
dengemann committed Nov 9, 2014
1 parent f2523e1 commit 5309c53
Show file tree
Hide file tree
Showing 79 changed files with 351 additions and 328 deletions.
13 changes: 7 additions & 6 deletions MANIFEST.in
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,13 @@ recursive-include mne *.py
recursive-include mne/data *.dat
recursive-include mne/data *.sel
recursive-include mne/data *.fif.gz
recursive-include mne/montages *.elc
recursive-include mne/montages *.txt
recursive-include mne/montages *.csd
recursive-include mne/montages *.sfp
recursive-include mne/layouts *.lout
recursive-include mne/layouts *.lay
recursive-include mne/channels/data/montages *.elc
recursive-include mne/channels/data/montages *.txt
recursive-include mne/channels/data/montages *.csd
recursive-include mne/channels/data/montages *.sfp
recursive-include mne/channels/data/layouts *.lout
recursive-include mne/channels/data/layouts *.lay
recursive-include mne/channels/data/neighbors *.mat
recursive-include mne/html *.js
recursive-include mne/html *.css
recursive-exclude examples/MNE-sample-data *
Expand Down
15 changes: 6 additions & 9 deletions doc/source/python_reference.rst
Original file line number Diff line number Diff line change
Expand Up @@ -318,27 +318,24 @@ Projections:
read_proj
write_proj

Set sensors locations for processing and plotting:
Manipulate channels and set sensors locations for processing and plotting:

.. currentmodule:: mne.montages
.. currentmodule:: mne.channels

.. autosummary::
:toctree: generated/
:template: function.rst

read_montage
apply_montage

.. currentmodule:: mne.layouts

.. autosummary::
:toctree: generated/
:template: function.rst

read_layout
find_layout
make_eeg_layout
make_grid_layout
read_ch_connectivity
equalize_channels
rename_channels
ch_neighbor_connectivity

:py:mod:`mne.preprocessing`:

Expand Down
5 changes: 5 additions & 0 deletions doc/source/whats_new.rst
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ Changelog

- Add support for montage files by `Denis Engemann`_, `Marijn van Vliet`_ and `Alex Gramfort`_.

- Add support for spatiotemporal permutation clustering on sensors by `Denis Engemann`_

BUG
~~~

Expand Down Expand Up @@ -60,6 +62,9 @@ API

- find_events and read_events functions have a new parameter `mask` to set some bits to a don't care state by `Teon Brooks`_

- New channels module including layouts, electrode montages, and neighbor definitions of sensors which deprecates
``mne.layouts`` by `Denis Engemann`_


.. _changes_0_8:

Expand Down
83 changes: 41 additions & 42 deletions examples/stats/plot_spatio_temporal_cluster_stats_sensor.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
"""
======================================================
Spatio-temporal permutation F-test on full sensor data
======================================================
=====================================================
Spatiotemporal permutation F-test on full sensor data
=====================================================
Tests for differential evoked responses in at least
one condition.
one condition using a permutation clustering test.
The the FieldTrip neighbor templates will be used to determine
the adjacency between sensors. This serves as a spatial prior
to the clustering. Significant spatiotemporal clusters will then
visualized using custom matplotlib code.
"""

# Authors: Denis Engemann <[email protected]>
Expand All @@ -21,6 +25,7 @@
from mne.datasets import sample

###############################################################################

# Set parameters
data_path = sample.data_path()
raw_fname = data_path + '/MEG/sample/sample_audvis_filt-0-40_raw.fif'
Expand Down Expand Up @@ -50,16 +55,18 @@
X = [epochs[k].get_data() for k in condition_names] # as 3D matrix
X = [np.transpose(x, (0, 2, 1)) for x in X] # transpose for clustering

from mne.channels import read_ch_connectivity

connectivity = read_ch_connectivity('neuromag306mag_neighb.mat')
# load FieldTrip neighbor definition to setup sensor connectivity
from mne.channels import read_ch_connectivity
connectivity = read_ch_connectivity('neuromag306mag_neighb')

###############################################################################
# Compute statistic

# set cluster threshold
threshold = 50.0 # very high, but the test is quite sensitive on this data
# set family-wise p-value
p_accept = 0.001
threshold = 50.0 # unrealistic high, but the test is sensitive on this data

cluster_stats = spatio_temporal_cluster_test(X, n_permutations=1000,
threshold=threshold, tail=1,
Expand All @@ -68,17 +75,13 @@

T_obs, clusters, p_values, _ = cluster_stats
good_cluster_inds = np.where(p_values < p_accept)[0]

# get sensor positions via layout
pos = mne.layouts.find_layout(epochs.info).pos


###############################################################################
# Visualize clusters

# load viz libraries
# load viz functionality
import matplotlib.pyplot as plt
from mpl_toolkits.axes_grid1 import make_axes_locatable
from mne.viz import plot_topomap

# configure variables for visualization
times = epochs.times * 1e3
Expand All @@ -88,67 +91,63 @@
# grand average as numpy arrray
grand_ave = np.array(X).mean(1)

for i_clu, clu_idx in enumerate(good_cluster_inds):
good_clu = np.squeeze(clusters[clu_idx])
time_inds, space_inds = good_clu

title = 'Cluster #{0}'.format(i_clu + 1)
# get sensor positions via layout
pos = mne.layouts.find_layout(epochs.info).pos

# get unique indices from cluster
# loop over significant clusters
for i_clu, clu_idx in enumerate(good_cluster_inds):
# unpack cluster infomation, get unique indices
time_inds, space_inds = np.squeeze(clusters[clu_idx])
ch_inds = np.unique(space_inds)
time_inds = np.unique(time_inds)

# get topography for F stat
f_map = T_obs[time_inds, ...].mean(0)

# get signals at significant sensors
signals = grand_ave[..., ch_inds].mean(-1)
sig_times = times[time_inds]

# create spatial mask
mask = np.zeros((f_map.shape[0], 1), dtype=bool)
mask[ch_inds, :] = True

# initialize figure
fig, ax_topo = plt.subplots(1, 1, figsize=(20, 5))
title = 'Cluster #{0}'.format(i_clu + 1)
fig.suptitle(title, fontsize=20)

# plot topo image
image, _ = mne.viz.plot_topomap(f_map, pos, mask=mask, axis=ax_topo,
cmap='Reds', vmin=np.min, vmax=np.max)

# plot average test statistic and mark significant sensors
image, _ = plot_topomap(f_map, pos, mask=mask, axis=ax_topo,
cmap='Reds', vmin=np.min, vmax=np.max)
# advanced matplotlib for showing image with figure and colorbar
# in one plot
divider = make_axes_locatable(ax_topo)

# add axes for colorbar
ax_colorbar = divider.append_axes('right', size='5%', pad=0.05)
plt.colorbar(image, cax=ax_colorbar)

ax_topo.set_xlabel('Averaged F-map ({:0.1f} - {:0.1f} ms)'.format(
*sig_times[[0, -1]]
))

# add new axis for time courses
# add new axis for time courses and plot time courses
ax_signals = divider.append_axes('right', size='300%', pad=1.2)

# plot time courses
for signal, name, col, ls in zip(signals,
condition_names,
colors,
for signal, name, col, ls in zip(signals, condition_names, colors,
linestyles):
ax_signals.plot(times, signal, color=col,
linestyle=ls, label=name)
ax_signals.plot(times, signal, color=col, linestyle=ls, label=name)

# add information
ax_signals.axvline(0, color='k', linestyle=':', label='stimulus onset')
ax_signals.set_xlim(*times[[0, -1]])
ax_signals.set_xlabel('time [ms]')
ax_signals.set_ylabel('evoked magnetic fields [fT]')


# plot significant time range
ymin, ymax = ax_signals.get_ylim()
ax_signals.fill_betweenx((ymin, ymax), sig_times[0],
sig_times[-1],
color='orange', alpha=0.3)
ax_signals.fill_betweenx((ymin, ymax), sig_times[0], sig_times[-1],
color='orange', alpha=0.3)
ax_signals.legend(loc='lower right')
ax_signals.set_ylim(ymin, ymax)

Expand Down
5 changes: 2 additions & 3 deletions mne/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,9 +56,9 @@
compute_proj_evoked, compute_proj_raw, sensitivity_map)
from .selection import read_selection
from .dipole import read_dip
from .layouts.layout import find_layout
from . import channels
from .channels import (equalize_channels, rename_channels,
read_ch_connectivity)
read_ch_connectivity, find_layout)

from . import beamformer
from . import commands
Expand All @@ -80,7 +80,6 @@
from . import viz
from . import decoding
from . import realtime
from . import montages

# initialize logging
set_log_level(None, False)
Expand Down
5 changes: 5 additions & 0 deletions mne/channels/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
from .layout import (Layout, make_eeg_layout, make_grid_layout, read_layout,
find_layout, read_montage, apply_montage)

from . channels import (equalize_channels, rename_channels,
read_ch_connectivity, ch_neighbor_connectivity)
32 changes: 18 additions & 14 deletions mne/channels.py → mne/channels/channels.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,11 @@
from scipy.io import loadmat
from scipy import sparse

from .externals.six import string_types
from ..externals.six import string_types

from .utils import verbose, logger
from .io.pick import channel_type, pick_info
from .io.constants import FIFF
from ..utils import verbose, logger
from ..io.pick import channel_type, pick_info
from ..io.constants import FIFF


def _get_meg_system(info):
Expand Down Expand Up @@ -92,10 +92,10 @@ def equalize_channels(candidates, verbose=None):
Note. This function operates inplace.
"""
from .io.base import _BaseRaw
from .epochs import Epochs
from .evoked import Evoked
from .time_frequency import AverageTFR
from ..io.base import _BaseRaw
from ..epochs import Epochs
from ..evoked import Evoked
from ..time_frequency import AverageTFR

if not all([isinstance(c, (_BaseRaw, Epochs, Evoked, AverageTFR))
for c in candidates]):
Expand Down Expand Up @@ -176,10 +176,10 @@ def drop_channels(self, ch_names, copy=False):

def _pick_drop_channels(self, idx):
# avoid circular imports
from .io.base import _BaseRaw
from .epochs import Epochs
from .evoked import Evoked
from .time_frequency import AverageTFR
from ..io.base import _BaseRaw
from ..epochs import Epochs
from ..evoked import Evoked
from ..time_frequency import AverageTFR

if isinstance(self, (_BaseRaw, Epochs)):
if not self.preload:
Expand Down Expand Up @@ -283,6 +283,10 @@ def _recursive_flatten(cell, dtype):
def read_ch_connectivity(fname, picks=None):
"""Parse FieldTrip neighbors .mat file
More information on these neighbor definitions can be found on the
related FieldTrip documentation pages:
http://fieldtrip.fcdonders.nl/template/neighbours
Parameters
----------
fname : str
Expand All @@ -298,9 +302,9 @@ def read_ch_connectivity(fname, picks=None):
"""
if not op.isabs(fname):
templates_dir = op.realpath(op.join(op.dirname(__file__),
'neighbors'))
'data', 'neighbors'))
templates = os.listdir(templates_dir)
if not any(f not in templates for f in (fname, fname + '.mat')):
if not any(f in templates for f in (fname, fname + '.mat')):
raise ValueError('I do not know about this neighbor '
'template: "{}"'.format(fname))
else:
Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
-42.19 43.52 -41.7 28.71
-42.19 43.52 -41.7 28.71
001 9.78 -14.18 4.00 3.00 MEG 001
002 3.31 -16.56 4.00 3.00 MEG 002
003 12.02 -19.42 4.00 3.00 MEG 003
Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
6 changes: 6 additions & 0 deletions mne/channels/data/neighbors/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# Neighbor definitions for clustering permutation analysis.
# This is a selection of files from http://fieldtrip.fcdonders.nl/template
# Additional definitions can be obtained through the FieldTrip software.
# For additional information on how these definitions were computed, please
# consider the related fieldtrip documentation:
# http://fieldtrip.fcdonders.nl/template/neighbours.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
Loading

0 comments on commit 5309c53

Please sign in to comment.