neighborhoods¶
Spatial neighborhood computation for neuroimaging analyses.
This module provides efficient computation and caching of spatial neighborhoods (spheres) around brain voxels. It is designed to support searchlight analyses, ISC, and other operations that require iterating over local brain regions.
The key insight is that for a given mask and radius, the neighborhood structure is deterministic and can be cached for reuse across analyses.
Example
import nibabel as nib from nltools.data.braindata.neighborhoods import compute_searchlight_neighborhoods
mask = nib.load(“mask.nii.gz”) neighborhoods = compute_searchlight_neighborhoods(mask, radius_mm=10.0)
Iterate over all voxels and their neighborhoods¶
for center_idx, neighbor_indices in neighborhoods.iter_neighborhoods(): ... # Extract data for these voxels ... local_data = data[:, neighbor_indices] ... result[center_idx] = analyze(local_data)
Classes:
| Name | Description |
|---|---|
SphereNeighborhoods | Precomputed sphere neighborhoods for a brain mask. |
Methods:
| Name | Description |
|---|---|
compute_searchlight_neighborhoods | Compute sphere neighborhoods for all voxels in a brain mask. |
Classes¶
SphereNeighborhoods¶
SphereNeighborhoods(adjacency: sparse.csr_matrix, mask_hash: str, radius_mm: float, n_voxels: int) -> NonePrecomputed sphere neighborhoods for a brain mask.
This dataclass stores a sparse adjacency matrix where row i contains True for all voxels within the specified radius of voxel i. It provides efficient iteration over neighborhoods for searchlight-style analyses.
Attributes:
| Name | Type | Description |
|---|---|---|
adjacency | csr_matrix | Sparse CSR matrix (n_voxels, n_voxels) where adjacency[i, j] is True if voxel j is within radius of voxel i |
mask_hash | str | Hash of the source mask for validation |
radius_mm | float | Radius in millimeters |
n_voxels | int | Number of voxels in the mask |
Example
neighborhoods = compute_searchlight_neighborhoods(mask, radius_mm=10.0) print(f"Mean neighborhood size: {neighborhoods.mean_size:.1f} voxels")
Get neighbors of a specific voxel¶
neighbor_idx = neighborhoods.get_neighbors(100) print(f"Voxel 100 has {len(neighbor_idx)} neighbors")
Methods:
| Name | Description |
|---|---|
get_neighborhood_size | Get the number of voxels in a neighborhood. |
get_neighbors | Get indices of all voxels in the neighborhood of a given voxel. |
iter_neighborhoods | Iterate over all neighborhoods. |
Methods¶
get_neighborhood_size¶
get_neighborhood_size(voxel_idx: int) -> intGet the number of voxels in a neighborhood.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
voxel_idx | int | Index of the center voxel | required |
Returns:
| Type | Description |
|---|---|
int | Number of voxels in the neighborhood |
get_neighbors¶
get_neighbors(voxel_idx: int) -> np.ndarrayGet indices of all voxels in the neighborhood of a given voxel.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
voxel_idx | int | Index of the center voxel (0 to n_voxels-1) | required |
Returns:
| Type | Description |
|---|---|
ndarray | Array of voxel indices within radius of the center voxel |
iter_neighborhoods¶
iter_neighborhoods(*, progress_bar: bool = False) -> Iterator[tuple[int, np.ndarray]]Iterate over all neighborhoods.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
progress_bar | bool | If True, wrap iterator with tqdm progress bar | False |
Yields:
| Type | Description |
|---|---|
tuple [ int , ndarray ] | Tuple of (center_voxel_idx, neighbor_indices) for each voxel |
Methods¶
compute_searchlight_neighborhoods¶
compute_searchlight_neighborhoods(mask_img: Nifti1Image, radius_mm: float = 10.0, use_cache: bool = True) -> SphereNeighborhoodsCompute sphere neighborhoods for all voxels in a brain mask.
For each voxel in the mask, this function identifies all other voxels within the specified radius (in millimeters). The result is cached to disk for fast reloading in subsequent analyses.
The algorithm uses sklearn’s BallTree for efficient radius queries in world coordinates (mm), ensuring accurate neighborhoods regardless of voxel resolution.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
mask_img | Nifti1Image | NIfTI mask image defining the brain region | required |
radius_mm | float | Radius of spheres in millimeters (default: 10.0) | 10.0 |
use_cache | bool | If True, cache results to ~/.nltools/cache/searchlight/ for fast reloading (default: True) | True |
Returns:
| Type | Description |
|---|---|
SphereNeighborhoods | SphereNeighborhoods with precomputed adjacency matrix |
Example
import nibabel as nib mask = nib.load(“brain_mask.nii.gz”)
First call computes and caches (may take a few seconds)¶
neighborhoods = compute_searchlight_neighborhoods(mask, radius_mm=8.0)
Subsequent calls load from cache (~50ms)¶
neighborhoods = compute_searchlight_neighborhoods(mask, radius_mm=8.0)
print(neighborhoods) SphereNeighborhoods(n_voxels=50000, radius=8.0mm, mean_size=33.2)
Note
Cache location: ~/.nltools/cache/searchlight/{mask_hash}_{radius}mm.npz
For a typical 2mm MNI mask (~50k voxels) with 10mm radius:
First run: ~1-2 seconds
Cached load: ~50ms