# MNE permutation cluster test

**URL:** <https://mne.discourse.group/t/mne-permutation-cluster-test/11438>\
**Category:** Support & Discussions\
**Tags:** eeg, statistics\
**Created:** [August 14, 2025, 6:55pm UTC](https://mne.discourse.group/t/mne-permutation-cluster-test/11438 "2025-08-14T18:55:36Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![ShahrzadAyoubipour](https://yyz2.discourse-cdn.com/free1/user_avatar/mne.discourse.group/shahrzadayoubipour/32/3641_2.png) [@ShahrzadAyoubipour](https://mne.discourse.group/u/ShahrzadAyoubipour)\
**Post date:** [August 14, 2025, 6:55pm UTC](https://mne.discourse.group/t/mne-permutation-cluster-test/11438/1 "2025-08-14T18:55:36Z")

</div>

Hello!

I have 3 groups of participants. PD ON medication, PD OFF medication, and Healthy control (PD group are same participants but 2 different conditions).  
I plan to run **paired** cluster permutation between PD ON and PD OFF as following:

```python
contra_mov_on_power_mu_array = np.array(contra_mov_on_power_mu) # (n_observations, n_channels, times) --> (20, 1, 1025)

contra_mov_off_power_mu_array = np.array(contra_mov_off_power_mu)

contra_mov_on_power_mu_array_T = np.transpose(contra_mov_on_power_mu_array, (0,2,1)) # --> (20, 1025, 1)

contra_mov_off_power_mu_array_T = np.transpose(contra_mov_off_power_mu_array, (0,2,1))

X_contra_mov_mu = np.subtract(contra_mov_on_power_mu_array_T, contra_mov_off_power_mu_array_T).squeeze()
 
print(X_contra_mov_mu.shape) # --> (20, 1025)

t_contra_mov_mu, clusters_contra_mov_mu, cluster_pv_contra_mov_mu, H0_contra_mov_mu = mne.stats.permutation_cluster_1samp_test(
    X_contra_mov_mu, threshold=None, n_permutations=10000, tail=0)

```

Based on the inputs I have, the above permutation will run **2 tailed** 1samp ttest.

I plan to run **unpaired** cluster permutation between PD ON and HC or PD OFF and HC as following:

```python
contra_mov_on_power_mu_array = np.array(contra_mov_on_power_mu) # --> (20, 1, 705) (n_observations, n_channels, times)
contra_mov_hc_power_mu_array = np.array(contra_mov_hc_power_mu) # --> (23, 1, 705)

contra_mov_on_power_mu_array_T = np.squeeze(np.transpose(contra_mov_on_power_mu_array, (0,2,1))) # --> (20, 705)

contra_mov_hc_power_mu_array_T = np.squeeze(np.transpose(contra_mov_hc_power_mu_array, (0,2,1))) # --> (23, 705)

X_contra_mov_on_hc_mu = [contra_mov_on_power_mu_array_T, contra_mov_hc_power_mu_array_T]

F_obs_contra_mov_on_hc_mu, clusters_contra_mov_on_hc_mu, cluster_pvals_contra_mov_on_hc_mu, H0_contra_mov_on_hc_mu = mne.stats.permutation_cluster_test(
    X_contra_mov_on_hc_mu, threshold=None, n_permutations=10000, tail=0)

```

Based on MNE explanation, when I do not specify _stat\_fun_ and put tail=0 for unpaired condition, this would run **1 tailed** one-way anova.

I want to run 2 tailed for both paired and unpaired to be consistent. So, I can put _stat\_fun_ input in unpaired function (`mne.stats.permutation_cluster_test`) as _ttest\_ind_ to run 2 tailed ttest. But, I understood in that case, MNE does not calculate threshold for tstat.

What is the right approach to handle this to be consistent?

Thank you in advance!

Best,

Shahrzad

---

<div class="post-metadata">

**Author:** ![CarinaFo](https://yyz2.discourse-cdn.com/free1/user_avatar/mne.discourse.group/carinafo/32/746_2.png) [@CarinaFo](https://mne.discourse.group/u/CarinaFo)\
**Post date:** [August 15, 2025, 6:55am UTC](https://mne.discourse.group/t/mne-permutation-cluster-test/11438/2 "2025-08-15T06:55:32Z")

</div>

Hi Shahrzad,

As far as I understand defining tail=0 runs a two tailed F test (2 groups) or t-test (paired sample). I do think if you use the code you provided you are consistent, I do remember (not 100 % sure but pretty confident) that a unpaired two sample t-test is equivalent to a one way ANOVA (or at least gives you the same p-value).

Cheers,

Carina

---

<div class="post-metadata">

**Author:** ![ShahrzadAyoubipour](https://yyz2.discourse-cdn.com/free1/user_avatar/mne.discourse.group/shahrzadayoubipour/32/3641_2.png) [@ShahrzadAyoubipour](https://mne.discourse.group/u/ShahrzadAyoubipour)\
**Post date:** [August 19, 2025, 9:40pm UTC](https://mne.discourse.group/t/mne-permutation-cluster-test/11438/3 "2025-08-19T21:40:39Z")

</div>

Thank you for your response, Carina!

when I put tail=0 for unpaired cluster permutation (`mne.stats.permutation_cluster_test`), MNE says:

```python
Ignoring argument "tail", performing 1-tailed F-test

```

But, do you think still I am consistent between my paired and unpaired comparisons based on the code I provided?

Thank you!

Shahrzad

---

<div class="post-metadata">

**Author:** ![CarinaFo](https://yyz2.discourse-cdn.com/free1/user_avatar/mne.discourse.group/carinafo/32/746_2.png) [@CarinaFo](https://mne.discourse.group/u/CarinaFo)\
**Post date:** [August 21, 2025, 1:06am UTC](https://mne.discourse.group/t/mne-permutation-cluster-test/11438/4 "2025-08-21T01:06:51Z")

</div>

Yes, the 1-tailed F-test is just more handy because we are looking at a variance ratio, so it’s enough to test one side (especially for df = 1).

Hope that helps?

---

<div class="post-metadata">

**Author:** ![system](https://global.discourse-cdn.com/free1/uploads/mne/original/1X/85cc6bd2b69cb698a166dc6d880fb550510d0144.jpeg) [@system](https://mne.discourse.group/u/system)\
**Post date:** [September 3, 2025, 12:11am UTC](https://mne.discourse.group/t/mne-permutation-cluster-test/11438/5 "2025-09-03T00:11:03Z")

</div>

This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.
