or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

data-io.mddatasets.mdindex.mdmachine-learning.mdpreprocessing.mdsource-analysis.mdstatistics.mdtime-frequency.mdvisualization.md

statistics.mddocs/

0

# Statistical Analysis

1

2

Statistical methods including cluster-based permutation testing, multiple comparisons correction, and specialized analysis tools designed for neuroimaging data with high temporal and spatial resolution.

3

4

## Capabilities

5

6

### Multiple Comparisons Correction

7

8

Correct for multiple comparisons across time, frequency, and spatial dimensions.

9

10

```python { .api }

11

def bonferroni_correction(pvals: ArrayLike, alpha: float = 0.05) -> Tuple[ArrayLike, float]:

12

"""

13

Bonferroni correction for multiple comparisons.

14

15

Parameters:

16

- pvals: P-values to correct

17

- alpha: Family-wise error rate

18

19

Returns:

20

Tuple of (reject array, corrected alpha level)

21

"""

22

23

def fdr_correction(pvals: ArrayLike, alpha: float = 0.05, method: str = 'indep') -> Tuple[ArrayLike, ArrayLike]:

24

"""

25

False discovery rate correction.

26

27

Parameters:

28

- pvals: P-values to correct

29

- alpha: False discovery rate

30

- method: FDR method ('indep' or 'negcorr')

31

32

Returns:

33

Tuple of (reject array, corrected p-values)

34

"""

35

```

36

37

### Cluster-Based Permutation Testing

38

39

Non-parametric statistical testing that accounts for multiple comparisons by clustering adjacent significant tests.

40

41

```python { .api }

42

def permutation_cluster_test(X: ArrayLike, threshold: Optional[float] = None, n_permutations: int = 1024,

43

tail: int = 0, stat_fun: Optional[callable] = None,

44

adjacency: Optional[ArrayLike] = None, n_jobs: int = 1,

45

seed: Optional[int] = None, max_step: int = 1, exclude: Optional[ArrayLike] = None,

46

step_down_p: float = 0, t_power: float = 1, out_type: str = 'indices',

47

check_disjoint: bool = False, buffer_size: Optional[int] = None,

48

verbose: Optional[Union[bool, str, int]] = None) -> Tuple:

49

"""

50

Cluster-based permutation test for comparing conditions.

51

52

Parameters:

53

- X: Data arrays to compare (list of arrays or single array)

54

- threshold: Statistical threshold for clustering

55

- n_permutations: Number of permutations

56

- tail: Test direction (0=two-tailed, 1=greater, -1=less)

57

- stat_fun: Statistical function to use

58

- adjacency: Adjacency matrix for clustering

59

- n_jobs: Number of parallel jobs

60

- seed: Random seed for reproducibility

61

- max_step: Maximum cluster step size

62

- exclude: Samples to exclude from clustering

63

- step_down_p: Step-down p-value threshold

64

- t_power: Power for threshold-free cluster enhancement

65

- out_type: Output type ('indices' or 'mask')

66

- check_disjoint: Check for disjoint clusters

67

- buffer_size: Buffer size for permutations

68

- verbose: Verbosity level

69

70

Returns:

71

Tuple of (T_obs, clusters, cluster_p_values, H0)

72

"""

73

74

def permutation_cluster_1samp_test(X: ArrayLike, threshold: Optional[float] = None, n_permutations: int = 1024,

75

tail: int = 0, stat_fun: Optional[callable] = None,

76

adjacency: Optional[ArrayLike] = None, n_jobs: int = 1,

77

seed: Optional[int] = None, max_step: int = 1,

78

exclude: Optional[ArrayLike] = None, step_down_p: float = 0,

79

t_power: float = 1, out_type: str = 'indices',

80

check_disjoint: bool = False, buffer_size: Optional[int] = None,

81

verbose: Optional[Union[bool, str, int]] = None) -> Tuple:

82

"""

83

One-sample cluster-based permutation test.

84

85

Parameters:

86

- X: Data array (n_observations, n_features)

87

- threshold: Statistical threshold for clustering

88

- n_permutations: Number of permutations

89

- tail: Test direction

90

- stat_fun: Statistical function

91

- adjacency: Adjacency matrix for clustering

92

- n_jobs: Number of parallel jobs

93

- seed: Random seed

94

- max_step: Maximum cluster step size

95

- exclude: Samples to exclude

96

- step_down_p: Step-down p-value threshold

97

- t_power: Power for TFCE

98

- out_type: Output type

99

- check_disjoint: Check for disjoint clusters

100

- buffer_size: Buffer size

101

- verbose: Verbosity level

102

103

Returns:

104

Tuple of (T_obs, clusters, cluster_p_values, H0)

105

"""

106

107

def spatio_temporal_cluster_test(X: ArrayLike, adjacency: ArrayLike, threshold: Optional[float] = None,

108

n_permutations: int = 1024, tail: int = 0, stat_fun: Optional[callable] = None,

109

n_jobs: int = 1, seed: Optional[int] = None, max_step: int = 1,

110

exclude: Optional[ArrayLike] = None, step_down_p: float = 0,

111

t_power: float = 1, out_type: str = 'indices',

112

check_disjoint: bool = False, buffer_size: Optional[int] = None,

113

verbose: Optional[Union[bool, str, int]] = None) -> Tuple:

114

"""

115

Spatio-temporal cluster-based permutation test.

116

117

Parameters:

118

- X: Data arrays (list of n_conditions arrays of shape n_observations × n_vertices × n_times)

119

- adjacency: Spatial adjacency matrix

120

- threshold: Statistical threshold

121

- n_permutations: Number of permutations

122

- tail: Test direction

123

- stat_fun: Statistical function

124

- n_jobs: Number of parallel jobs

125

- seed: Random seed

126

- max_step: Maximum cluster step size

127

- exclude: Samples to exclude

128

- step_down_p: Step-down threshold

129

- t_power: TFCE power

130

- out_type: Output type

131

- check_disjoint: Check disjointness

132

- buffer_size: Buffer size

133

- verbose: Verbosity level

134

135

Returns:

136

Tuple of (T_obs, clusters, cluster_p_values, H0)

137

"""

138

139

def spatio_temporal_cluster_1samp_test(X: ArrayLike, adjacency: ArrayLike, threshold: Optional[float] = None,

140

n_permutations: int = 1024, tail: int = 0,

141

stat_fun: Optional[callable] = None, n_jobs: int = 1,

142

seed: Optional[int] = None, max_step: int = 1,

143

exclude: Optional[ArrayLike] = None, step_down_p: float = 0,

144

t_power: float = 1, out_type: str = 'indices',

145

check_disjoint: bool = False, buffer_size: Optional[int] = None,

146

verbose: Optional[Union[bool, str, int]] = None) -> Tuple:

147

"""

148

One-sample spatio-temporal cluster test.

149

150

Parameters:

151

- X: Data array (n_observations × n_vertices × n_times)

152

- adjacency: Spatial adjacency matrix

153

- threshold: Statistical threshold

154

- n_permutations: Number of permutations

155

- tail: Test direction

156

- stat_fun: Statistical function

157

- n_jobs: Number of parallel jobs

158

- seed: Random seed

159

- max_step: Maximum cluster step size

160

- exclude: Samples to exclude

161

- step_down_p: Step-down threshold

162

- t_power: TFCE power

163

- out_type: Output type

164

- check_disjoint: Check disjointness

165

- buffer_size: Buffer size

166

- verbose: Verbosity level

167

168

Returns:

169

Tuple of (T_obs, clusters, cluster_p_values, H0)

170

"""

171

```

172

173

### Parametric Statistical Tests

174

175

Classical parametric tests adapted for neuroimaging data structures.

176

177

```python { .api }

178

def f_oneway(*args: ArrayLike) -> Tuple[ArrayLike, ArrayLike]:

179

"""

180

One-way ANOVA F-test.

181

182

Parameters:

183

- *args: Data arrays for each group

184

185

Returns:

186

Tuple of (F-statistics, p-values)

187

"""

188

189

def f_mway_rm(data: ArrayLike, factor_levels: ArrayLike, effects: str = 'A*B',

190

correction: bool = False, alpha: float = 0.05) -> Dict:

191

"""

192

Multi-way repeated measures ANOVA.

193

194

Parameters:

195

- data: Data array (n_subjects × n_conditions × n_times)

196

- factor_levels: Number of levels for each factor

197

- effects: Effects to test ('A', 'B', 'A*B', etc.)

198

- correction: Apply sphericity correction

199

- alpha: Significance level

200

201

Returns:

202

Dictionary with F-statistics, p-values, and effect information

203

"""

204

205

def ttest_1samp_no_p(X: ArrayLike, popmean: float = 0, sigma: Optional[float] = None) -> ArrayLike:

206

"""

207

One-sample t-test without p-value computation (for speed).

208

209

Parameters:

210

- X: Data array

211

- popmean: Population mean to test against

212

- sigma: Standard deviation (if known)

213

214

Returns:

215

T-statistics array

216

"""

217

218

def ttest_ind_no_p(X1: ArrayLike, X2: ArrayLike, equal_var: bool = True) -> ArrayLike:

219

"""

220

Independent samples t-test without p-values.

221

222

Parameters:

223

- X1: First group data

224

- X2: Second group data

225

- equal_var: Assume equal variances

226

227

Returns:

228

T-statistics array

229

"""

230

```

231

232

### Non-Parametric Tests and Bootstrap

233

234

Non-parametric alternatives and bootstrap methods for statistical inference.

235

236

```python { .api }

237

def permutation_t_test(X: ArrayLike, n_permutations: int = 10000, tail: int = 0,

238

n_jobs: int = 1, seed: Optional[int] = None,

239

verbose: Optional[Union[bool, str, int]] = None) -> Tuple[ArrayLike, ArrayLike]:

240

"""

241

Permutation-based t-test.

242

243

Parameters:

244

- X: Data array (n_observations, n_features)

245

- n_permutations: Number of permutations

246

- tail: Test direction (0=two-tailed, 1=greater, -1=less)

247

- n_jobs: Number of parallel jobs

248

- seed: Random seed

249

- verbose: Verbosity level

250

251

Returns:

252

Tuple of (T-statistics, p-values)

253

"""

254

255

def bootstrap_confidence_interval(arr: ArrayLike, ci: float = 0.95, n_bootstraps: int = 10000,

256

stat_fun: str = 'mean', seed: Optional[int] = None,

257

n_jobs: int = 1, verbose: Optional[Union[bool, str, int]] = None) -> ArrayLike:

258

"""

259

Bootstrap confidence intervals.

260

261

Parameters:

262

- arr: Data array

263

- ci: Confidence interval level

264

- n_bootstraps: Number of bootstrap samples

265

- stat_fun: Statistic to compute ('mean', 'median', 'std')

266

- seed: Random seed

267

- n_jobs: Number of parallel jobs

268

- verbose: Verbosity level

269

270

Returns:

271

Confidence interval bounds

272

"""

273

```

274

275

### Linear Regression Analysis

276

277

Regression methods for relating neural signals to experimental variables.

278

279

```python { .api }

280

def linear_regression(design_matrix: ArrayLike, data: ArrayLike, names: Optional[List[str]] = None) -> Dict:

281

"""

282

Compute linear regression.

283

284

Parameters:

285

- design_matrix: Design matrix (n_observations × n_regressors)

286

- data: Data matrix (n_observations × n_features)

287

- names: Regressor names

288

289

Returns:

290

Dictionary with regression coefficients, t-statistics, p-values, etc.

291

"""

292

293

def linear_regression_raw(raw: Raw, design_matrix: ArrayLike, names: Optional[List[str]] = None,

294

tmin: float = 0.0, tmax: Optional[float] = None,

295

reject_by_annotation: bool = True, picks: Optional[Union[str, List]] = None) -> Dict:

296

"""

297

Linear regression on raw data.

298

299

Parameters:

300

- raw: Raw data instance

301

- design_matrix: Design matrix

302

- names: Regressor names

303

- tmin: Start time

304

- tmax: End time

305

- reject_by_annotation: Reject annotated segments

306

- picks: Channel selection

307

308

Returns:

309

Dictionary with regression results

310

"""

311

```

312

313

### Adjacency Matrices and Clustering Utilities

314

315

Construct spatial adjacency matrices for cluster-based statistics.

316

317

```python { .api }

318

def combine_adjacency(adjacency_list: List[ArrayLike]) -> ArrayLike:

319

"""

320

Combine multiple adjacency matrices.

321

322

Parameters:

323

- adjacency_list: List of adjacency matrices

324

325

Returns:

326

Combined adjacency matrix

327

"""

328

329

def spatial_src_adjacency(src: SourceSpaces, verbose: Optional[Union[bool, str, int]] = None) -> ArrayLike:

330

"""

331

Compute adjacency matrix for source space.

332

333

Parameters:

334

- src: Source space

335

- verbose: Verbosity level

336

337

Returns:

338

Source space adjacency matrix

339

"""

340

341

def spatial_tris_adjacency(tris: ArrayLike, remap_vertices: bool = False) -> ArrayLike:

342

"""

343

Compute adjacency matrix from triangulation.

344

345

Parameters:

346

- tris: Triangle array (n_tris × 3)

347

- remap_vertices: Remap vertex indices

348

349

Returns:

350

Spatial adjacency matrix

351

"""

352

353

def spatial_dist_adjacency(src: SourceSpaces, dist: float, verbose: Optional[Union[bool, str, int]] = None) -> ArrayLike:

354

"""

355

Compute distance-based adjacency matrix.

356

357

Parameters:

358

- src: Source space with distance information

359

- dist: Maximum distance for adjacency

360

- verbose: Verbosity level

361

362

Returns:

363

Distance-based adjacency matrix

364

"""

365

366

def spatial_inter_hemi_adjacency(src: SourceSpaces, dist: float,

367

verbose: Optional[Union[bool, str, int]] = None) -> ArrayLike:

368

"""

369

Get inter-hemisphere adjacency.

370

371

Parameters:

372

- src: Source space

373

- dist: Maximum inter-hemisphere distance

374

- verbose: Verbosity level

375

376

Returns:

377

Inter-hemisphere adjacency matrix

378

"""

379

```

380

381

### Cluster Analysis and Summarization

382

383

Analyze and summarize results from cluster-based permutation tests.

384

385

```python { .api }

386

def summarize_clusters_stc(clu: Tuple, tstep: float, tmin: float, subject: str,

387

vertices: Optional[List[ArrayLike]] = None,

388

verbose: Optional[Union[bool, str, int]] = None) -> List[Dict]:

389

"""

390

Summarize cluster test results in source space.

391

392

Parameters:

393

- clu: Cluster test results tuple

394

- tstep: Time step

395

- tmin: Start time

396

- subject: Subject name

397

- vertices: Vertex arrays (if different from clu)

398

- verbose: Verbosity level

399

400

Returns:

401

List of cluster summary dictionaries

402

"""

403

```

404

405

## Usage Examples

406

407

### Basic Cluster-Based Permutation Test

408

409

```python

410

import mne

411

from mne.stats import permutation_cluster_test

412

import numpy as np

413

414

# Load epochs for two conditions

415

epochs1 = mne.read_epochs('condition1-epo.fiv')

416

epochs2 = mne.read_epochs('condition2-epo.fiv')

417

418

# Get data arrays

419

X = [epochs1.get_data(), epochs2.get_data()]

420

421

# Run cluster-based permutation test

422

T_obs, clusters, cluster_p_values, H0 = permutation_cluster_test(

423

X, n_permutations=1000, threshold=None, tail=0, n_jobs=1)

424

425

# Find significant clusters

426

significant_clusters = [c for c, p in zip(clusters, cluster_p_values) if p < 0.05]

427

print(f"Found {len(significant_clusters)} significant clusters")

428

```

429

430

### Spatio-Temporal Cluster Test

431

432

```python

433

import mne

434

from mne.stats import spatio_temporal_cluster_1samp_test

435

436

# Load epochs

437

epochs = mne.read_epochs('sample-epo.fiv')

438

439

# Get data (subtract baseline)

440

X = epochs.get_data() - epochs.get_data().mean(axis=-1, keepdims=True)

441

442

# Create adjacency matrix for channels

443

adjacency, ch_names = mne.channels.find_ch_adjacency(epochs.info, ch_type='eeg')

444

445

# Run spatio-temporal cluster test

446

T_obs, clusters, cluster_p_values, H0 = spatio_temporal_cluster_1samp_test(

447

X, adjacency=adjacency, n_permutations=1000, threshold=None, tail=1)

448

449

# Visualize results

450

evoked = mne.EvokedArray(T_obs, epochs.info, tmin=epochs.tmin)

451

evoked.plot_topomap(times=np.linspace(0.05, 0.3, 6))

452

```

453

454

### Source Space Cluster Test

455

456

```python

457

import mne

458

from mne.stats import spatio_temporal_cluster_1samp_test, summarize_clusters_stc

459

460

# Load source estimates for multiple subjects

461

stcs = []

462

for subject in subjects:

463

stc = mne.read_source_estimate(f'{subject}-stc.fiv')

464

stcs.append(stc)

465

466

# Convert to array (n_subjects × n_vertices × n_times)

467

X = np.array([stc.data for stc in stcs])

468

469

# Get source space adjacency

470

src = mne.read_source_spaces('fsaverage-oct6-src.fiv')

471

adjacency = mne.spatial_src_adjacency(src)

472

473

# Run cluster test

474

T_obs, clusters, cluster_p_values, H0 = spatio_temporal_cluster_1samp_test(

475

X, adjacency=adjacency, n_permutations=1000, threshold=None, tail=1)

476

477

# Summarize significant clusters

478

significant_clusters = summarize_clusters_stc(

479

(T_obs, clusters, cluster_p_values, H0),

480

tstep=stcs[0].tstep, tmin=stcs[0].tmin, subject='fsaverage')

481

482

# Create source estimate with T-statistics

483

stc_T = mne.SourceEstimate(T_obs, vertices=stcs[0].vertices,

484

tmin=stcs[0].tmin, tstep=stcs[0].tstep,

485

subject='fsaverage')

486

stc_T.plot(subject='fsaverage', subjects_dir=subjects_dir)

487

```

488

489

### Multiple Comparisons Correction

490

491

```python

492

import mne

493

from mne.stats import fdr_correction, bonferroni_correction

494

import numpy as np

495

496

# Simulate p-values from multiple tests

497

n_tests = 1000

498

p_values = np.random.uniform(0, 1, n_tests)

499

p_values[:50] = np.random.uniform(0, 0.01, 50) # Add some "significant" values

500

501

# Apply FDR correction

502

reject_fdr, p_fdr = fdr_correction(p_values, alpha=0.05)

503

print(f"FDR: {np.sum(reject_fdr)} significant tests")

504

505

# Apply Bonferroni correction

506

reject_bonf, alpha_bonf = bonferroni_correction(p_values, alpha=0.05)

507

print(f"Bonferroni: {np.sum(reject_bonf)} significant tests")

508

print(f"Bonferroni corrected alpha: {alpha_bonf}")

509

```

510

511

### Linear Regression Analysis

512

513

```python

514

import mne

515

from mne.stats import linear_regression

516

import numpy as np

517

518

# Load epochs

519

epochs = mne.read_epochs('sample-epo.fiv')

520

521

# Create design matrix (e.g., stimulus intensity)

522

n_epochs = len(epochs)

523

stimulus_intensity = np.random.randn(n_epochs)

524

design_matrix = np.column_stack([np.ones(n_epochs), stimulus_intensity])

525

526

# Get data

527

data = epochs.get_data().reshape(n_epochs, -1) # Flatten channels and time

528

529

# Run regression

530

results = linear_regression(design_matrix, data,

531

names=['Intercept', 'Stimulus_Intensity'])

532

533

# Extract results

534

beta = results['beta'] # Regression coefficients

535

t_val = results['t_val'] # T-statistics

536

p_val = results['p_val'] # P-values

537

538

# Reshape back to original dimensions

539

n_channels, n_times = epochs.get_data().shape[1:]

540

t_val_reshaped = t_val[1].reshape(n_channels, n_times) # Stimulus effect

541

542

# Create evoked with T-statistics

543

evoked_t = mne.EvokedArray(t_val_reshaped, epochs.info, tmin=epochs.tmin)

544

evoked_t.plot_topomap(times=[0.1, 0.2, 0.3])

545

```

546

547

## Types

548

549

```python { .api }

550

import numpy as np

551

from typing import Union, Optional, List, Dict, Tuple, Any, Callable

552

553

ArrayLike = Union[np.ndarray, List, Tuple]

554

```