Skip to content

lijiaxiang63/GrouVox

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

24 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

GrouVox

Voxel-wise group-level statistical analysis for neuroimaging data.

GrouVox performs two-sample t-tests and voxel-wise regression on NIfTI brain images with optional covariates (age, sex, etc.), outputs T-statistic maps, and applies multiple comparison correction using Gaussian Random Field (GRF) theory or False Discovery Rate (FDR).

Installation

# From source
git clone https://github.com/lijiaxiang63/GrouVox
cd GrouVox
uv sync

Quick Start

Python API

import grouvox

# Two-sample t-test
result = grouvox.two_sample_ttest(
    group1="data/patients/",
    group2="data/controls/",
    output="results/group_comparison",
    mask="brain_mask.nii.gz",
    covariates="covariates.csv",  # CSV with age, sex, etc.
    contrast=[1, -1],             # patients > controls
)

print(f"DOF: {result.dof}, FWHM: {result.fwhm}")

# Voxel-wise regression: image ~ predictor + covariates
reg_result = grouvox.regression(
    images="data/subjects/",
    predictor="predictor.csv",   # single-column CSV, one value per subject
    output="results/regression",
    mask="brain_mask.nii.gz",
    covariates="covariates.csv",  # optional nuisance regressors
)

# GRF cluster-level correction
grf_result = grouvox.grf_correction(
    "results/group_comparison_T.nii.gz",
    mask_path="brain_mask.nii.gz",
    voxel_p=0.001,
    cluster_p=0.05,
    reestimate=False,  # True to re-estimate smoothness from the Z-map
)

print(f"Cluster size threshold: {grf_result.cluster_size_threshold} voxels")
for c in grf_result.cluster_table:
    mni = c["peak_coords_mni"]
    print(f"  Cluster {c['label']}: {c['size']} voxels, peak Z={c['peak_value']:.2f} at MNI ({mni[0]:.0f}, {mni[1]:.0f}, {mni[2]:.0f})")
    for atlas, regions in c["atlas_regions"].items():
        for r in regions:
            print(f"    {atlas}: {r['pct']:.1f}% {r['name']}")

# FDR correction
fdr_result = grouvox.fdr_correction(
    "results/group_comparison_T.nii.gz",
    mask_path="brain_mask.nii.gz",
    q=0.05,
)

print(f"FDR p-threshold: {fdr_result.p_threshold:.6f}")
print(f"Significant voxels: {fdr_result.n_significant}")
print(f"Clusters: {fdr_result.n_clusters}")
for c in fdr_result.cluster_table:
    mni = c["peak_coords_mni"]
    print(f"  Cluster {c['label']}: {c['size']} voxels at MNI ({mni[0]:.0f}, {mni[1]:.0f}, {mni[2]:.0f})")

CLI

# Two-sample t-test
grouvox ttest2 \
    --group1 data/patients/ \
    --group2 data/controls/ \
    --output results/group_comparison \
    --mask brain_mask.nii.gz \
    --covariates covariates.csv \
    --contrast 1 -1

# Voxel-wise regression: image ~ predictor + covariates
grouvox regress \
    --images data/subjects/ \
    --predictor predictor.csv \
    --covariates covariates.csv \
    --mask brain_mask.nii.gz \
    --output results/regression

# GRF correction
grouvox correct \
    --input results/group_comparison_T.nii.gz \
    --method grf \
    --voxel-p 0.001 \
    --cluster-p 0.05 \
    --mask brain_mask.nii.gz

# GRF correction with smoothness re-estimation from the Z-map
grouvox correct \
    --input results/group_comparison_T.nii.gz \
    --method grf \
    --voxel-p 0.001 \
    --cluster-p 0.05 \
    --mask brain_mask.nii.gz \
    --reestimate

# FDR correction
grouvox correct \
    --input results/group_comparison_T.nii.gz \
    --method fdr \
    --q 0.05 \
    --mask brain_mask.nii.gz

Covariate File Format

A CSV file where each row is a subject (for ttest2: group 1 first, then group 2; for regress: same order as the images) and each column is a covariate:

age,sex
25,0
30,1
28,0
...

Predictor File Format (regression)

A single-column CSV giving the continuous variable of interest, one value per subject in the same order as the images:

score
12.4
9.8
14.1
...

Output Files

T-test / regression outputs

File Description
{output}_T.nii.gz T-statistic map (from contrast, or predictor slope for regression)
{output}_beta.nii.gz Beta coefficients (4D: one volume per regressor)
{output}_cohen_f2.nii.gz Cohen's f² effect size map

GRF correction outputs

File Description
Z_ClusterThresholded_{name}.nii.gz Thresholded Z-map
ClusterThresholded_{name}.nii.gz Thresholded original T-map
ClusterReport_{name}.csv Cluster table with atlas annotations

FDR correction outputs

File Description
FDR_Thresholded_{name}.nii.gz FDR-thresholded T-map
ClusterReport_{name}.csv Cluster table with atlas annotations

Statistical Methods

Design Matrix

Two-sample t-test uses a cell-means parameterization:

X = [G1, G2, Cov1, Cov2, ...]
  • G1: indicator for group 1 (1 for group 1, 0 for group 2)
  • G2: indicator for group 2
  • Contrast [1, -1] tests group 1 > group 2

Regression uses an intercept + predictor parameterization:

X = [1, predictor, Cov1, Cov2, ...]
  • The T-map tests the predictor slope (contrast [0, 1, 0, ...]), i.e. whether voxel values covary with the predictor after accounting for covariates.

GRF Correction

Implements cluster-level inference based on Gaussian Random Field theory (Friston et al., 1994):

  1. Converts T-map to Z-map
  2. Estimates smoothness from the Z-map (if --reestimate is set or header metadata is missing), otherwise reads smoothness (dLh) from the NIfTI header
  3. Applies voxel-level threshold
  4. Calculates cluster size threshold from expected Euler characteristic (cluster_p is halved per tail in two-tailed mode)
  5. Removes clusters below threshold (26-connectivity)

FDR Correction

Implements the Benjamini-Hochberg procedure to control the false discovery rate. Surviving voxels are grouped into clusters via 26-connectivity labeling.

Atlas-Based Cluster Annotation

Both GRF and FDR results annotate each surviving cluster using three bundled atlases:

  • AAL (Automated Anatomical Labeling)
  • HarvardOxford-cortical
  • HarvardOxford-subcortical

Each cluster reports:

  • Peak voxel MNI coordinates and atlas label at the peak
  • Region overlap percentages (proportion of cluster voxels in each atlas region)
  • Results are written to a ClusterReport CSV file and printed by the CLI

Development

uv sync
uv run pytest tests/ -v

References

  • Friston, K. J., et al. (1994). Assessing the significance of focal activations using their spatial extent. Human Brain Mapping, 1(3), 210-220.
  • Benjamini, Y., & Hochberg, Y. (1995). Controlling the false discovery rate. JRSS-B, 57(1), 289-300.
  • Worsley, K. J., et al. (1999). Detecting changes in nonisotropic images. Human Brain Mapping, 8(2-3), 98-101.

About

Voxel-wise group-level statistical analysis for neuroimaging (NIfTI, OLS, GRF/FDR correction)

Resources

Stars

Watchers

Forks

Packages

 
 
 

Contributors

Languages