From f66f663e0f4e049bc948ba126f046ec20c8f9788 Mon Sep 17 00:00:00 2001 From: Daniel McCloy Date: Fri, 30 Apr 2021 15:07:05 -0500 Subject: [PATCH 1/7] better docs [skip azp][skip actions] --- mne/utils/docs.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/mne/utils/docs.py b/mne/utils/docs.py index 435fcc3149e..9a4160bb532 100644 --- a/mne/utils/docs.py +++ b/mne/utils/docs.py @@ -1782,7 +1782,7 @@ stat_fun : callable | None Function called to calculate the test statistic. Must accept 1D-array as input and return a 1D array. If ``None`` (the default), uses - :func:`mne.stats.{}`. + `mne.stats.{}`. """ docdict['clust_stat_f'] = docdict['clust_stat'].format('f_oneway') docdict['clust_stat_t'] = docdict['clust_stat'].format('ttest_1samp_no_p') @@ -1803,10 +1803,11 @@ 'a square matrix with dimension ``{x}.shape[-1]`` (n_vertices) to save ' 'memory and computation, and to use ``max_step`` to define the extent ' 'of temporal adjacency to consider when clustering.') +comb = ' The function `mne.stats.combine_adjacency` may be useful for 4D data.' st = dict(sp='spatial', lastdim='', parone='(n_vertices)', partwo='(n_times * n_vertices)', memory=mem) tf = dict(sp='', lastdim=' (or the last two dimensions if ``{x}`` is 2D)', - parone='', partwo='', memory='') + parone='(for 3D data)', partwo='(for 4D data)', memory=comb) nogroups = dict(eachgrp='', x='X') groups = dict(eachgrp='each group ', x='X[k]') docdict['clust_adj_st1'] = docdict['clust_adj'].format(**st).format(**nogroups) From 92f14502c4832b554c2df47e9e0f5d7c489280a1 Mon Sep 17 00:00:00 2001 From: Daniel McCloy Date: Fri, 30 Apr 2021 15:36:45 -0500 Subject: [PATCH 2/7] add note to combine_adjacency --- mne/stats/_adjacency.py | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/mne/stats/_adjacency.py b/mne/stats/_adjacency.py index c81344a8aef..d5f94da62c7 100644 --- a/mne/stats/_adjacency.py +++ b/mne/stats/_adjacency.py @@ -28,6 +28,18 @@ def combine_adjacency(*structure): ------- adjacency : scipy.sparse.coo_matrix, shape (n_features, n_features) The adjacency matrix. + + Notes + ----- + For 4-dimensional data with shape ``(n_obs, n_times, n_freqs, n_chans)``, + you can specify **no** connectivity along a particular dimension by passing + a matrix of zeros. For example: + + >>> _time = n_times # regular lattice connectivity + >>> _freq = np.zeros((n_freqs, n_freqs)) # no adjacency between freq. bins + >>> _chan = scipy.sparse.diags([1., 1.], offsets=(-1, 1), + shape=(n_chans, n_chans)) # just for examp. + >>> combine_adjacency(_time, _freq, _chan) """ from scipy import sparse structure = list(structure) From b31e1e56b67e6e12845c70cf7336db3b368b88e0 Mon Sep 17 00:00:00 2001 From: Daniel McCloy Date: Fri, 30 Apr 2021 15:36:55 -0500 Subject: [PATCH 3/7] simplify --- mne/stats/_adjacency.py | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/mne/stats/_adjacency.py b/mne/stats/_adjacency.py index d5f94da62c7..6e722a3e310 100644 --- a/mne/stats/_adjacency.py +++ b/mne/stats/_adjacency.py @@ -47,15 +47,11 @@ def combine_adjacency(*structure): name = f'structure[{di}]' _validate_type(dim, ('int-like', np.ndarray, sparse.spmatrix), name) if isinstance(dim, int_like): - dim = int(dim) - # Don't add the diagonal, because we explicitly remove it later: - # dim = sparse.eye(dim, format='coo') - # dim += sparse.eye(dim.shape[0], k=1, format='coo') - # dim += sparse.eye(dim.shape[0], k=-1, format='coo') - ii, jj = np.arange(0, dim - 1), np.arange(1, dim) - edges = np.vstack([np.hstack([ii, jj]), np.hstack([jj, ii])]) - dim = sparse.coo_matrix( - (np.ones(edges.shape[1]), edges), (dim, dim), float) + # Don't add the diagonal, because we explicitly remove it later + dim = sparse.diags([1, 1], + offsets=(-1, 1), + shape=(int(dim), int(dim)), + dtype=float).tocoo() else: _check_option(f'{name}.ndim', dim.ndim, [2]) if dim.shape[0] != dim.shape[1]: From 0f7c433017142f55bbee43bfdd38d3377dc26d5f Mon Sep 17 00:00:00 2001 From: Daniel McCloy Date: Fri, 30 Apr 2021 15:40:34 -0500 Subject: [PATCH 4/7] consistent language --- mne/stats/_adjacency.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mne/stats/_adjacency.py b/mne/stats/_adjacency.py index 6e722a3e310..eb6a849c57e 100644 --- a/mne/stats/_adjacency.py +++ b/mne/stats/_adjacency.py @@ -32,10 +32,10 @@ def combine_adjacency(*structure): Notes ----- For 4-dimensional data with shape ``(n_obs, n_times, n_freqs, n_chans)``, - you can specify **no** connectivity along a particular dimension by passing + you can specify **no** connections along a particular dimension by passing a matrix of zeros. For example: - >>> _time = n_times # regular lattice connectivity + >>> _time = n_times # regular lattice adjacency >>> _freq = np.zeros((n_freqs, n_freqs)) # no adjacency between freq. bins >>> _chan = scipy.sparse.diags([1., 1.], offsets=(-1, 1), shape=(n_chans, n_chans)) # just for examp. From e673785620b9d05ca9dfeb7d1be08164450138f1 Mon Sep 17 00:00:00 2001 From: Daniel McCloy Date: Fri, 30 Apr 2021 15:41:10 -0500 Subject: [PATCH 5/7] formatting --- mne/stats/_adjacency.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mne/stats/_adjacency.py b/mne/stats/_adjacency.py index eb6a849c57e..6a733ae57cd 100644 --- a/mne/stats/_adjacency.py +++ b/mne/stats/_adjacency.py @@ -37,8 +37,8 @@ def combine_adjacency(*structure): >>> _time = n_times # regular lattice adjacency >>> _freq = np.zeros((n_freqs, n_freqs)) # no adjacency between freq. bins - >>> _chan = scipy.sparse.diags([1., 1.], offsets=(-1, 1), - shape=(n_chans, n_chans)) # just for examp. + >>> _chan = scipy.sparse.diags( + [1., 1.], offsets=(-1, 1), shape=(n_chans, n_chans)) # for example >>> combine_adjacency(_time, _freq, _chan) """ from scipy import sparse From 185c735555a5ddc27172649a7d70bd32e69d1a70 Mon Sep 17 00:00:00 2001 From: Daniel McCloy Date: Fri, 30 Apr 2021 17:58:28 -0500 Subject: [PATCH 6/7] fix doctest --- mne/stats/_adjacency.py | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/mne/stats/_adjacency.py b/mne/stats/_adjacency.py index 6a733ae57cd..7a435f3a292 100644 --- a/mne/stats/_adjacency.py +++ b/mne/stats/_adjacency.py @@ -35,11 +35,17 @@ def combine_adjacency(*structure): you can specify **no** connections along a particular dimension by passing a matrix of zeros. For example: - >>> _time = n_times # regular lattice adjacency - >>> _freq = np.zeros((n_freqs, n_freqs)) # no adjacency between freq. bins - >>> _chan = scipy.sparse.diags( - [1., 1.], offsets=(-1, 1), shape=(n_chans, n_chans)) # for example - >>> combine_adjacency(_time, _freq, _chan) + >>> import numpy as np + >>> from scipy.sparse import diags + >>> from mne.stats import combine_adjacency + >>> n_times, n_freqs, n_chans = (50, 7, 16) + >>> chan_adj = diags([1., 1.], offsets=(-1, 1), shape=(n_chans, n_chans)) + >>> combine_adjacency( + ... n_times, # regular lattice adjacency for times + ... np.zeros((n_freqs, n_freqs)), # no adjacency between freq. bins + ... chan_adj) # custom matrix, or use mne.channels.find_ch_adjacency + <5600x5600 sparse matrix of type '' + with 27076 stored elements in COOrdinate format> """ from scipy import sparse structure = list(structure) From 7d8d3752aeae385ee9e0050562978662c0e86581 Mon Sep 17 00:00:00 2001 From: Daniel McCloy Date: Mon, 3 May 2021 09:32:27 -0500 Subject: [PATCH 7/7] fix doctest for real --- mne/stats/_adjacency.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/mne/stats/_adjacency.py b/mne/stats/_adjacency.py index 7a435f3a292..8b0abf5bb67 100644 --- a/mne/stats/_adjacency.py +++ b/mne/stats/_adjacency.py @@ -32,8 +32,8 @@ def combine_adjacency(*structure): Notes ----- For 4-dimensional data with shape ``(n_obs, n_times, n_freqs, n_chans)``, - you can specify **no** connections along a particular dimension by passing - a matrix of zeros. For example: + you can specify **no** connections among elements in a particular + dimension by passing a matrix of zeros. For example: >>> import numpy as np >>> from scipy.sparse import diags @@ -43,7 +43,8 @@ def combine_adjacency(*structure): >>> combine_adjacency( ... n_times, # regular lattice adjacency for times ... np.zeros((n_freqs, n_freqs)), # no adjacency between freq. bins - ... chan_adj) # custom matrix, or use mne.channels.find_ch_adjacency + ... chan_adj, # custom matrix, or use mne.channels.find_ch_adjacency + ... ) # doctest: +NORMALIZE_WHITESPACE <5600x5600 sparse matrix of type '' with 27076 stored elements in COOrdinate format> """