conninfpy.tfnbs_score

Threshold-Free Network-Based Statistics (TFNBS) scoring module.

This module provides implementations of TFCE (Threshold-Free Cluster Enhancement) adapted for network/connectivity analysis. The main function is get_tfnbs_score() which transforms t-statistic matrices into TFNBS scores.

Functions

get_tfnbs_score : Main optimized TFNBS implementation using scipy get_tfnbs_score_baseline : Non-optimized version for benchmarking get_tfnbs_score_networkx : Legacy networkx implementation for comparison with other packages

conninfpy.tfnbs_score.get_tfnbs_score(t_stats: ndarray[tuple[Any, ...], dtype[floating]], e: float | List[float] | ndarray[tuple[Any, ...], dtype[floating]], h: float | List[float] | ndarray[tuple[Any, ...], dtype[floating]], n: int, start_thres: float = 1.65, backend: str = 'auto') ndarray[tuple[Any, ...], dtype[floating]][source]

Transform the connectivity matrix using Threshold-Free Network-Based Statistics.

Optimized implementation using scipy’s csgraph module with:

  • Pre-extracted edges to avoid repeated masking

  • Buffer reuse to minimize memory allocations

  • Vectorized cluster size computation

Parameters:
  • t_stats (ndarray of shape (N, N)) – Statistical matrix to be transformed.

  • e (float or array-like) – Extent exponent. Can be a scalar or list of values for parameter sweep.

  • h (float or array-like) – Height exponent. Can be a scalar or list of values for parameter sweep.

  • n (int) – Number of threshold steps between start_thres and max(t_stats).

  • start_thres (float, default=1.65) – Initial threshold for cluster formation.

  • backend ({'auto', 'numba', 'scipy'}, default='auto') – Computation backend. ‘auto’ uses numba if available, otherwise scipy. ‘numba’ uses JIT-compiled union-find for connected components (8-30x faster). Falls back to ‘scipy’ if numba is not installed.

Returns:

tfnbs – TFNBS score matrix. Shape is (N, N) if e and h are scalars, otherwise (N, N, num_params).

Return type:

ndarray of shape (N, N) or (N, N, num_params)

Examples

>>> t = np.array([[0, 2.1, 0.5],[2.1, 0, 2.5],[0.5, 2.5, 0]])
>>> np.round(get_tfnbs_score(t, e=0.5, h=2.0, n=10), 2)
array([[0.  , 2.19, 0.  ],
       [2.19, 0.  , 4.5 ],
       [0.  , 4.5 , 0.  ]])
conninfpy.tfnbs_score.get_network_informed_tfnbs_score(t_stats: ndarray[tuple[Any, ...], dtype[floating]], net_labels: ndarray[tuple[Any, ...], dtype[integer]], e: float | List[float] | ndarray[tuple[Any, ...], dtype[floating]], h: float | List[float] | ndarray[tuple[Any, ...], dtype[floating]], n: int, start_thres: float = 1.65, normalization: str = 'sqrt') ndarray[tuple[Any, ...], dtype[floating]][source]

Transform connectivity matrix using Network-Informed TFNBS (Edge-Level Weighting).

This method uses Edge-Level Weighting: each edge’s support depends only on the density of its functional block, with NO topological clustering. This prevents “signal bleeding” where noise edges inherit scores from signal clusters they happen to connect to.

Weighting Logic (depends on normalization):
  • 'sqrt': S_edge = k / sqrt(M_b) (default)

  • 'linear': S_edge = k / M_b (density)

  • 'none': S_edge = k (raw active count)

Key difference from standard TFNBS:
  • Standard TFNBS: edges cluster if they share a node (topological)

  • NI-TFNBS: each edge scored independently by block density

Parameters:
  • t_stats (ndarray of shape (N, N)) – Statistical matrix to be transformed.

  • net_labels (ndarray of shape (N,)) – Integer labels assigning each node to a functional network.

  • e (float or array-like) – Extent exponent.

  • h (float or array-like) – Height exponent.

  • n (int) – Number of threshold steps.

  • start_thres (float, default=1.65) – Initial threshold for cluster formation.

  • normalization ({'sqrt', 'linear', 'none'}, default='sqrt') – Block density normalization variant for ablation study.

Returns:

tfnbs – Network-Informed TFNBS score matrix.

Return type:

ndarray of shape (N, N) or (N, N, num_params)

conninfpy.tfnbs_score.get_fbc_tfnbs_score(t_stats: ndarray[tuple[Any, ...], dtype[floating]], net_labels: ndarray[tuple[Any, ...], dtype[integer]], e: float | List[float] | ndarray[tuple[Any, ...], dtype[floating]], h: float | List[float] | ndarray[tuple[Any, ...], dtype[floating]], n: int, start_thres: float = 1.65, min_cluster_size: int = 3) ndarray[tuple[Any, ...], dtype[floating]][source]

Functional Block Clustering TFNBS (FBC-TFNBS).

This method clusters edges by functional block membership rather than topological connectivity. At each threshold:

  1. Edges are grouped by their functional block (e.g., Visual-Visual, DMN-DMN)

  2. If a block has k >= min_cluster_size edges, those edges support each other (support = k)

  3. If a block has fewer edges, they are considered “isolated” and suppressed (support = 0)

Key difference from standard TFNBS:
  • Standard TFNBS: edges cluster if they share a node (topological)

  • FBC-TFNBS: edges cluster if they’re in the same functional block

Key difference from NI-TFNBS:
  • NI-TFNBS: topological clustering with density weighting (spreads to noise)

  • FBC-TFNBS: no topological clustering, isolated edges are suppressed

Parameters:
  • t_stats (ndarray of shape (N, N)) – Statistical matrix to be transformed (usually absolute t-values).

  • net_labels (ndarray of shape (N,)) – Integer labels assigning each node to a functional network.

  • e (float or array-like) – Extent exponent. Controls how much cluster size matters.

  • h (float or array-like) – Height exponent. Controls how much threshold height matters.

  • n (int) – Number of threshold steps between start_thres and max(t_stats).

  • start_thres (float, default=1.65) – Initial threshold for cluster formation.

  • min_cluster_size (int, default=3) – Minimum number of edges in a functional block to form a cluster. Blocks with fewer edges get support=0 (suppressed).

Returns:

tfnbs – FBC-TFNBS score matrix.

Return type:

ndarray of shape (N, N) or (N, N, num_params)

Notes

The key insight is that edges in the same functional block should support each other even if they don’t share any nodes. This captures the biological reality that effects within a functional system (e.g., Visual cortex) are likely related, while isolated edges are more likely noise.

Examples

>>> import numpy as np
>>> # Create a simple t-statistic matrix
>>> t = np.array([[0, 2.5, 1.8, 0.5],
...               [2.5, 0, 2.2, 0.3],
...               [1.8, 2.2, 0, 2.0],
...               [0.5, 0.3, 2.0, 0]])
>>> # Nodes 0,1 in network 0; nodes 2,3 in network 1
>>> labels = np.array([0, 0, 1, 1])
>>> scores = get_fbc_tfnbs_score(t, labels, e=0.5, h=2.0, n=20,
...                               start_thres=1.5, min_cluster_size=2)