✦ Day 19 · Statistics

TFCE Statistics
Threshold-Free Cluster Enhancement

A step-by-step walkthrough of how eTFCE calculates the exact topological score for a single target electrode — no arbitrary thresholds, just beautiful topology.

🧪 Simulated t value setup 📡 10 Channels · Alpha Power 🎯 Target: Fz 📊 Exact eTFCE

We simulate a resting-state EEG experiment comparing the Alpha Power of two groups across 10 channels. After running an independent-samples t-test at each electrode, we obtain one t-value per channel. The map below shows the raw statistical landscape we need TFCE to interpret.

Our target electrode is Fz, which sits at a respectable peak of t = +2.5. Rather than ask "is this number significant in isolation?", eTFCE asks: "How much topological support does this peak receive from its entire neighbourhood?"

Channel Physical Neighbors
(The Adjacency Web)
Alpha Power
(t-value)
Fpz F3, Fz, F4 +1.5
F3 Fpz, Fz, C3 +1.5
Fz  (Target) Fpz, F3, F4, Cz +2.5
F4 Fpz, Fz, C4 +1.5
C3 F3, Cz, P3 −1.2
Cz Fz, C3, C4, Pz 0.0
C4 F4, Cz, P4 −1.2
P3 C3, Pz −1.2
Pz Cz, P3, P4 −2.0
P4 C4, Pz 0.0

🗺 Interactive Adjacency Explorer

Hover over any electrode to reveal its physical neighbours on the scalp

Fpz +1.5 F3 +1.5 Fz ★ +2.5 F4 +1.5 C3 -1.2 Cz 0.0 C4 -1.2 P3 -1.2 Pz -2.0 P4 0.0 ANTERIOR POSTERIOR LEFT RIGHT

👆 Hover over an electrode to explore its adjacency

Positive t
Target (Fz)
Negative t
Zero
Active neighbour link

1

Phase 1 Splitting the Universes

Before any integration happens, eTFCE performs a polarity split. Positive and negative signals are separated into two independent universes to prevent zero-crossing crashes — a signed peak riding through zero would otherwise cancel itself out mid-calculation.

Our target electrode Fz has a t-value of +2.5, so it lives in the Positive Universe.

⊕ Positive Universe

Fpz: 1.5
F3:  1.5
Fz:  2.5
F4:  1.5
all others: 0.0

⊖ Negative Universe

Fz was positive, so it is locked to 0.0 here. It will accumulate exactly 0.00 mass in the negative tail — which we will use in the final recombination step.


2

Phase 2 Defining the Exact Slices (eTFCE)

The key difference between classical TFCE and exact TFCE (eTFCE) is how the integration steps are chosen. Instead of a user-defined step-size swept from zero to the maximum, eTFCE uses only the unique height values actually present in the data as its integration boundaries.

In the Positive Universe, the only values are 1.5 and 2.5. Because integration always starts from the "ground" (height = 0), this gives us exactly two horizontal slices:

Slice 1

From $0.0 \rightarrow 1.5$

Step height $\Delta h = 1.5$

Slice 2

From $1.5 \rightarrow 2.5$

Step height $\Delta h = 1.0$

Standard MEEG Parameters

We use the standard weights from Mensen & Khatami (2013):

  • Extent exponent $E = 0.5$   (i.e., square root of cluster size)
  • Height exponent $H = 2.0$   (i.e., height squared)
$$\text{Mass}_\text{slice} = e^{E} \cdot h^{H} \cdot \Delta h$$

where $e$ = cluster extent (number of electrodes), $h$ = threshold height of the slice, $\Delta h$ = slice thickness.


3

Phase 3 The Integration Loop for Fz

For each slice, the algorithm performs three sub-steps: (i) build a binary mask of surviving channels, (ii) trace the connected cluster containing Fz via the adjacency web, and (iii) accumulate the slice mass.

Slice 1 — Threshold $h = 1.5$  |  $\Delta h = 1.5$

The broad frontal foundation

Step i — Binary Mask. Every channel whose value $\geq 1.5$ becomes 1; the rest become 0.

Fpz (1.5) → 1
F3  (1.5) → 1
Fz  (2.5) → 1
F4  (1.5) → 1
C3 → 0
Cz → 0
C4 → 0
P3 → 0
Pz → 0
P4 → 0

Step ii — Adjacency Check. Fz is a 1. The algorithm traces its physical neighbors from the adjacency table:

  • Fpz → 1  (Connected)
  • F3  → 1  (Connected)
  • F4  → 1  (Connected)
  • Cz  → 0  (Bridge broken)

Fz, Fpz, F3, and F4 form a single, unbroken frontal cluster. The cluster extent $e = 4$.

Step iii — Calculate Mass for Fz at Slice 1:

$$\text{Mass} = \sqrt{4} \cdot (1.5)^2 \cdot 1.5 = 2 \cdot 2.25 \cdot 1.5 = \mathbf{6.75}$$
Slice 2 — Threshold $h = 2.5$  |  $\Delta h = 1.0$

The isolated peak

Step i — Binary Mask. The threshold rises to 2.5. Only channels with value $\geq 2.5$ survive.

Fpz (1.5) → 0 ↓
F3  (1.5) → 0 ↓
Fz  (2.5) → 1 ✓
F4  (1.5) → 0 ↓
C3 → 0
Cz → 0
C4 → 0
P3 → 0
Pz → 0
P4 → 0

Step ii — Adjacency Check. All frontal neighbours of Fz have dropped below the threshold and become 0. Fz now stands completely alone.

Fz is a cluster of one. The cluster extent $e = 1$.

Step iii — Calculate Mass for Fz at Slice 2:

$$\text{Mass} = \sqrt{1} \cdot (2.5)^2 \cdot 1.0 = 1 \cdot 6.25 \cdot 1.0 = \mathbf{6.25}$$

4

Phase 4 Final Recombination

The integration loop is complete. We now sum the per-slice masses from the Positive Universe and subtract any mass from the Negative Universe.

Universe Slice Mass Running Total
Positive Slice 1  ($h=1.5$, $e=4$) 6.75 6.75
Positive Slice 2  ($h=2.5$, $e=1$) 6.25 13.00
Negative Fz locked to 0 in this universe 0.00 0.00
eTFCEFz = Positive − Negative = 13.00 − 0.00 +13.00
$$\text{eTFCE}_{Fz} = \underbrace{6.75}_{\text{Slice 1}} + \underbrace{6.25}_{\text{Slice 2}} - \underbrace{0.00}_{\text{Negative}} = \mathbf{+13.00}$$
🎯

Final eTFCE Score — Electrode Fz

eTFCEFz = +13.00

Final Intuition Check What the Math is Really Saying

Look at how beautifully the mathematics mirrors the neuroscience.

Fz had a raw peak of +2.5. When it was at the top of its peak (Slice 2), it was standing alone — its cluster extent was 1, so it accumulated mass slowly (only $6.25$). This reflects the biological reality that an isolated peak, no matter how tall, carries limited interpretive weight.

But because Fz was resting on a broad, highly active frontal foundation (Slice 1 — the wide plateau shared with Fpz, F3, F4), its frontal neighbours literally pushed it up, donating a massive bonus of $6.75$ to its base. The cluster's spatial breadth was captured, not just the electrode's height.

By integrating both the broad foundation and the isolated peak, eTFCE successfully captured the total topological volume of electrode Fz — a quantity that is simultaneously sensitive to height and spatial extent, without any arbitrary threshold choice.

The practical upshot: TFCE will naturally score a tall, spatially isolated blip lower than a moderately tall but spatially broad cluster. This is exactly what we want — true neural effects tend to be topographically coherent, whereas noise spikes tend to be spatially isolated. TFCE exploits this distinction mathematically, giving you mass-univariate inference that respects the spatial structure of EEG data.


🌐

Key Concept The Bridge: How Clusters Grow Beyond Direct Neighbours

A sharp student looking at the adjacency table will notice something: F3 and F4 are not listed as direct neighbours of each other. They sit on opposite sides of the forehead. So why did they both end up in the same cluster of size e = 4 in Slice 1?

The answer reveals one of TFCE's most important — and most frequently misunderstood — properties: a cluster is a connected network, not just a collection of immediate neighbours.

📖 The Cluster Rule

To belong to the same cluster as another electrode, you do not need to touch it directly. You only need an unbroken chain of surviving 1s connecting you to it — like a path through a graph.

🔎 Tracing the Cluster: Slice 1 Mask

At threshold h = 1.5, the binary mask is:

Fpz → 1
F3  → 1
Fz  → 1
F4  → 1
C3 → 0
Cz → 0
C4 → 0
P3 → 0
Pz → 0
P4 → 0

Now trace the flood-fill algorithm starting from F4:

F4 checks its direct neighbours

From the adjacency table: F4's neighbours are Fpz, Fz, and C4. Check mask: Fpz = 1 ✓, Fz = 1 ✓, C4 = 0 ✗.
Cluster so far: {F4, Fpz, Fz} — extent = 3

Fpz and Fz act as bridges

The algorithm now expands from every newly added node. Both Fpz and Fz list F3 among their direct neighbours. F3's mask value is 1 ✓ — so F3 is absorbed into the cluster via this shared bridge.
Cluster grows: {F4, Fpz, Fz, F3} — extent = 4

No further growth

The frontier of newly-added nodes (F3) has neighbours C3 (mask = 0) and Cz (mask = 0). Both bridges are broken. The flood-fill terminates.
Final cluster: {Fpz, F3, Fz, F4} — e = 4 ✓

🌉 The Bridge Visualised

F3

+1.5

BRIDGE

Fpz

+1.5

BRIDGE

Fz ★

+2.5

BRIDGE

F4

+1.5

F3 and F4 are not direct neighbours — but they share a connected path through Fpz and Fz. One unbroken chain → one cluster.

❌ What If the Bridge Were Broken?

If Fpz = 0 & Fz = 0

F3 Fpz Fz F4

F3 = isolated cluster of e = 1
F4 = isolated cluster of e = 1
Both receive far less TFCE mass.

Reality: Fpz = 1 & Fz = 1

F3 Fpz Fz F4

One merged cluster of e = 4
All four electrodes share the same spatial bonus.
Far more TFCE mass for everyone.

The key insight: Every active electrode in a cluster is rewarded for the total spatial reach of the cluster — not just its own patch of cortex. An electrode sitting at the edge of a large network (like F3 or F4 here) receives the same extent bonus as the electrodes at the centre (Fpz, Fz). The middle electrodes act as spatial amplifiers, magnifying the statistical weight of every electrode they bridge together.


PS

Postscript — A Natural Follow-Up Question

When Can One Electrode Have Both Positive and Negative Mass?

An electrode has exactly one raw t-value at any given statistical snapshot. That value is either positive or negative — it cannot be both simultaneously. Therefore, for a single static map, the final TFCE equation always has one side guaranteed to be zero:

Positive electrode

13.00 − 0.00 = +13.00

Negative electrode

0.00 − 8.50 = −8.50

The equation is Positive − Negative. For any single electrode in a single static map, one of those two terms is mathematically locked to zero. There is no exception — it is a structural property of the polarity split.

⚡ The Only Exception — Adding Dimensions

The single situation where electrode Fz appears in the output with both a positive and a negative TFCE mass is when you move from a static snapshot to a multi-dimensional analysis — for example, running TFCE across a Channels × Time grid (as in ERP or time-frequency analyses in MNE-Python or FieldTrip).

In that setting, each data point is a unique (channel, time) coordinate. Fz at 100 ms and Fz at 200 ms are treated as two entirely separate data points by the algorithm.

📊 Worked Example — Fz over a 300 ms ERP Window

Imagine Fz's t-value evolves across time during a task:

Fz @ 100 ms

t = +3.0

Positive Universe → large mass

Fz @ 150 ms

t = +0.2

Positive Universe → tiny mass

Fz @ 200 ms

t = −2.5

Negative Universe → negative mass

When the algorithm processes the full 2-D grid, Fz's output array across time will contain both positive eTFCE scores (around 100 ms) and negative eTFCE scores (around 200 ms). But zoom into any single (Fz, t) coordinate — and the iron rule holds: it belongs to exactly one universe, and its score from the other is zero.

The iron rule, restated precisely: For any single data coordinate — whether that is (channel) in a static map or (channel, time) in an ERP — the raw value is either positive or negative, never both. It therefore belongs to exactly one universe. Its eTFCE score from the other universe is permanently zero. What changes in multi-dimensional data is that the same electrode label appears at many different coordinates, each with its own polarity and its own universe membership.

📚

Further reading

  1. Threshold Free Cluster Enhancement explained 📝
    Benedikt V. Ehinger — the definitive visual walkthrough of how TFCE works, with diagrams showing the height × extent integration across thresholds.
  2. Statistics: Cluster Permutation Test 📝
    Benedikt V. Ehinger — companion post explaining the permutation logic that gives TFCE scores their null distribution and p-values.
  3. Know your neighbours: how channels are connected spatially 📖
    FieldTrip FAQ — explains how ft_prepare_neighbours builds the adjacency graph that TFCE and cluster tests rely on.
  4. Cluster-based multiple comparisons correction 🎥
    Mike X Cohen — clear lecture on why cluster correction beats voxelwise FWE/FDR and how the permutation null distribution is built.
  5. Extreme pixel-based multiple comparisons correction 🎥
    Mike X Cohen — walks through the extreme-value (eTFCE-style) variant and how the maximum statistic distribution controls family-wise error.
  6. Correcting for multiple comparisons with cluster-based permutation 🎥
    Lecture video covering the full cluster-permutation pipeline — from forming clusters to building the null distribution and reading off p-values.
  7. Brief paper overview: Threshold free cluster enhancement 🎥
    A compact video walkthrough of the original Smith & Nichols (2009) TFCE paper — great for connecting the mathematical formalism to implementation.
  8. How should I interpret the results of a cluster-based permutation test? 📖
    FieldTrip FAQ — the authoritative guide to reading cluster-stat output correctly, including what the cluster p-value actually means and common misconceptions.
  9. Advent of code 🎥
    A programming puzzles advent calendar video walkthrough.
  10. Software carpentry programming with python 📖
    A great introduction to programming in Python.
  11. Python Data Science Handbook by Jake Vanderplas 📖
    A comprehensive guide to doing data science in Python.
  12. “You can't do data science in a GUI” -- by Hadley Wickham 🎥
    Hadley Wickham's insightful talk on why programmatic data science scales better.