8
8
logger = logging .getLogger ("frites" )
9
9
10
10
11
- RECENTER = dict (mean = np .mean , median = np .median ,
12
- trimmed = lambda x , axis = 0 : trim_mean (x , .2 , axis = axis ))
11
+ def _trimmed (x , prop = .2 , axis = 0 , keepdims = False ):
12
+ trm = trim_mean (x , prop , axis = axis )
13
+ if keepdims :
14
+ ax = [slice (None )] * x .ndim
15
+ ax [axis ] = np .newaxis
16
+ trm = trm [tuple (ax )]
17
+ return trm
18
+
19
+
20
+ RECENTER = {
21
+ 'mean' : np .mean , 'median' : np .median , 'zscore' : np .mean ,
22
+ 'trimmed' : _trimmed
23
+ }
24
+
25
+
26
+ def _recenter (x , fcn_mean , zscore , axis = - 1 ):
27
+ """Recentering function."""
28
+ _std = x .std (axis = axis , keepdims = True ) if zscore else 1.
29
+ return (x - fcn_mean (x , axis = axis , keepdims = True )) / _std
13
30
14
31
15
32
def ttest_1samp (x , pop_mean , axis = 0 , implementation = 'mne' , sigma = 0.001 , ** kw ):
@@ -50,7 +67,7 @@ def fcn(x, pop_mean, axis): # noqa
50
67
return fcn (x , pop_mean , axis )
51
68
52
69
53
- def rfx_ttest (mi , mi_p , center = False , zscore = False , ttested = False ):
70
+ def rfx_ttest (mi , mi_p , center = False , sigma = 0.001 , ttested = False ):
54
71
"""Perform the t-test across subjects.
55
72
56
73
Parameters
@@ -61,12 +78,12 @@ def rfx_ttest(mi, mi_p, center=False, zscore=False, ttested=False):
61
78
mi_p : array_like
62
79
A list of array of permuted mutual information of shape
63
80
(n_perm, n_suj, n_times). If `ttested` is True, n_suj shoud be 1.
64
- center : {'mean', 'median', 'trimmed'} | False
65
- If True, substract the mean of the surrogates to the true and permuted
66
- mi. The median or the 20% trimmed mean can also be removed
67
- :cite:`wilcox2018guide`
68
- zscore : bool | False
69
- Apply z-score normalization to the true and permuted mutual information
81
+ sigma : float | 0.001
82
+ Hat adjustment method, a value of 1e-3 may be a reasonable choice
83
+ center : {False, 'mean', ' median', ' trimmed', 'zscore'}
84
+ Re-center the time-series of effect arround 0 before computing the
85
+ t-test. This parameters can be useful in case of a different number
86
+ of data per brain region.
70
87
ttested : bool | False
71
88
Specify if the inputs have already been t-tested
72
89
@@ -93,14 +110,17 @@ def rfx_ttest(mi, mi_p, center=False, zscore=False, ttested=False):
93
110
n_roi = len (mi_p )
94
111
95
112
# remove the mean / median / trimmed
113
+ zscore = center == 'zscore'
96
114
if center in RECENTER .keys ():
97
- logger .info (f" RFX recenter distributions (center={ center } , "
98
- f"z-score={ zscore } )" )
99
- for k in range (len (mi )):
100
- _med = RECENTER [center ](mi_p [k ], axis = 0 )
101
- _std = mi_p [k ].std (axis = 0 ) if zscore else 1.
102
- mi [k ] = (mi [k ] - _med ) / _std
103
- mi_p [k ] = (mi_p [k ] - _med ) / _std
115
+ # get the centering function
116
+ fcn_mean = RECENTER [center ]
117
+
118
+ # here, we need to make a copy of the effect sizes to avoid changing
119
+ # the ouputs
120
+ mi , mi_p = mi .copy (), mi_p .copy ()
121
+ for k in range (n_roi ):
122
+ mi [k ] = _recenter (mi [k ], fcn_mean , zscore , axis = - 1 ).copy ()
123
+ mi_p [k ] = _recenter (mi_p [k ], fcn_mean , zscore , axis = - 1 ).copy ()
104
124
105
125
# get the mean of surrogates (low ram method)
106
126
n_element = np .sum ([np .prod (k .shape ) for k in mi_p ])
@@ -112,12 +132,14 @@ def rfx_ttest(mi, mi_p, center=False, zscore=False, ttested=False):
112
132
that the MNE t-test is going to evaluate one sigma per roi. To fix that,
113
133
we estimate this sigma using the variance of all of the data
114
134
"""
115
- from frites .config import CONFIG
116
- s_hat = CONFIG ['TTEST_MNE_SIGMA' ]
135
+ s_hat = sigma
117
136
118
137
# sigma on true mi and permuted mi
119
- sigma = s_hat * max ([np .var (k , axis = 0 , ddof = 1 ).max () for k in mi ])
120
- sigma_p = s_hat * max ([np .var (k , axis = 1 , ddof = 1 ).max () for k in mi_p ])
138
+ if s_hat > 0 :
139
+ sigma = s_hat * max ([np .var (k , axis = 0 , ddof = 1 ).max () for k in mi ])
140
+ sigma_p = s_hat * max ([np .var (k , axis = 1 , ddof = 1 ).max () for k in mi_p ])
141
+ else :
142
+ sigma = sigma_p = 0.
121
143
logger .debug (f"sigma_true={ sigma } ; sigma_permuted={ sigma_p } " )
122
144
kw = dict (implementation = 'mne' , method = 'absolute' , sigma = sigma )
123
145
kw_p = dict (implementation = 'mne' , method = 'absolute' , sigma = sigma_p )
0 commit comments