14.2.1. Cai et al. (2025). The Hemodynamic Response Function Varies Across Anatomical Location and …¶
Introduction¶
Here we present commands used in the following paper:
- Cai Z, von Ellenrieder N, Arafat T, Kho HM, Chen G, Koupparis A, Abdallah C, Dudley R, Nguyen DK, Hall J, Dubeau F, Gotman J, Bernhardt B (2025). The Hemodynamic Response Function Varies Across Anatomical Location and Pathology in the Epileptic Brain. (submitted)
Abstract: The hemodynamic response function (HRF) links neuronal activity to functional magnetic resonance imaging (fMRI) signals. While most fMRI studies use a “canonical” HRF, increasing evidence from studies of healthy subjects suggests that the HRF depends on anatomical location and disease states. Here, we investigate how HRF variability relates to anatomical location and pathology in the epileptic brain, using a large simultaneous electroencephalogram and fMRI dataset. Applying HRF deconvolution and temporal decomposition, we built the first whole-brain HRF library specific to epilepsy, identifying four distinct shape groups. We mapped HRF features across parcellations of two atlases using novel Bayesian hierarchical models. In non-epileptogenic regions, HRF shape and spatial distributions align with findings from healthy subjects. Within pathological regions, they vary significantly according to pathology. Our results indicate that HRF variability is associated with pathology, in addition to its dependence on anatomical location, motivating region- and pathology-based HRF modulation in epilepsy studies.
Study keywords: Epilepsy, HRF, EEG-fMRI, Pathology, Bayesian hierarchical modeling
Main programs:
@SUMA_Make_Spec_FS, @SSwarper, afni_proc.py
Download scripts¶
To download, either:
... click the link(s) in the following table (perhaps Rightclick -> “Save Link As…”):
run
@SUMA_Make_Spec_FS(after FreeSurfer’srecon-all) to convert the volumetric datasets into NIFTI format and the surfaces into standardized meshes in GIFTI formatrun
@SSwarperskullstripping and nonlinear warping to template spacerun
afni_proc.pyfor task-based FMRI analysis; this uses nonlinear warps estimated with@SSwarper... or copy+paste into a terminal:
curl -O https://afni.nimh.nih.gov/pub/dist/doc/htmldoc/codex/fmri/media/2026_CaiEtal/do_00_fssuma.bash curl -O https://afni.nimh.nih.gov/pub/dist/doc/htmldoc/codex/fmri/media/2026_CaiEtal/do_01_ssw.bash curl -O https://afni.nimh.nih.gov/pub/dist/doc/htmldoc/codex/fmri/media/2026_CaiEtal/do_02_ap.bash
View scripts¶
The scripts shown here contain full examples of the per-subject commands created by the above GitHub repository’s Python implementation.
do_00_fssuma.bash¶
1#!/bin/bash
2#SBATCH --account=def-jgotman
3#SBATCH --job-name=sub-ep0568_FSSUMA.job
4#SBATCH --output=/scratch/djangoc/EP_EEGfMRI_deconvolution/sub-ep0568_FSSUMA.out
5#SBATCH --error=/scratch/djangoc/EP_EEGfMRI_deconvolution/sub-ep0568_FSSUMA.err
6#SBATCH --time=5:00:00
7#SBATCH --cpus-per-task=8
8#SBATCH --mem-per-cpu=4G
9#SBATCH --mail-user=zhengchen.cai@gmail.com
10#SBATCH --mail-type=BEGIN
11#SBATCH --mail-type=END
12#SBATCH --mail-type=FAIL
13
14export FREESURFER_HOME=$HOME/freesurfer
15
16source $FREESURFER_HOME/SetUpFreeSurfer.sh
17
18module load StdEnv/2020 gcc/9.3.0 afni/23.1.08
19
20p1=/scratch/djangoc/EP_EEGfMRI_deconvolution/derivatives/freesurfer_AFNIUAC
21p2=/home/djangoc/projects/def-jgotman/djangoc/EP_EEGfMRI_deconvolution
22p3=${p2}/derivatives/afni/sub-ep0568/anat
23
24recon-all \
25 -all \
26 -3T \
27 -sd ${p1} \
28 -subjid sub-ep0568 \
29 -i ${p3}/anatUAC.sub-ep0568.nii \
30 -parallel
31
32@SUMA_Make_Spec_FS \
33 -fs_setup \
34 -NIFTI \
35 -sid sub-ep0568 \
36 -fspath ${p1}/sub-ep0568
do_01_ssw.bash¶
This command uses ``@SSwarper`` for combined skullstripping and nonlinear warping. In subsequent work, it has been updated to use the more modern version of this program in AFNI, ``sswarper2``, which has similar purpose, option usage and integration with ``afni_proc.py``.
1#!/bin/bash
2#SBATCH --account=def-jgotman
3#SBATCH --job-name=sub-ep0568_SSwarper.job
4#SBATCH --output=/scratch/djangoc/EP_EEGfMRI_deconvolution/sub-ep0568_SSwarper.out
5#SBATCH --error=/scratch/djangoc/EP_EEGfMRI_deconvolution/sub-ep0568_SSwarper.err
6#SBATCH --time=3:00:00
7#SBATCH --cpus-per-task=8
8#SBATCH --mem-per-cpu=4G
9#SBATCH --mail-user=zhengchen.cai@gmail.com
10#SBATCH --mail-type=BEGIN
11#SBATCH --mail-type=END
12#SBATCH --mail-type=FAIL
13
14module load StdEnv/2020 gcc/9.3.0 afni/23.1.08
15
16p2=/home/djangoc/projects/def-jgotman/djangoc/EP_EEGfMRI_deconvolution
17p4=/scratch/djangoc/EP_EEGfMRI_deconvolution/sub-ep0568/anat
18
19time @SSwarper \
20 -tmp_name_nice \
21 -base ${p2}/derivatives/MNI152_2009_template_SSW.nii.gz \
22 -subid sub-ep0568 \
23 -input ${p2}/sub-ep0568/anat/sub-ep0568_T1w.nii.gz \
24 -odir ${p4}
do_02_ap.bash¶
The FMRI processing here makes use of the TENT deconvolution approach used by Chen et al. (2023).
1#!/bin/bash
2#SBATCH --account=def-jgotman
3#SBATCH --job-name=sub-ep0568_afniproc_TENT_orig_dm.job
4#SBATCH --output=/scratch/djangoc/EP_EEGfMRI_deconvolution/derivatives/afni/sub-ep0568_TENT_orig_dm.out
5#SBATCH --error=/scratch/djangoc/EP_EEGfMRI_deconvolution/derivatives/afni/sub-ep0568_TENT_orig_dm.err
6#SBATCH --time=5:00:00
7#SBATCH --cpus-per-task=16
8#SBATCH --mem-per-cpu=4G
9#SBATCH --mail-user=zhengchen.cai@gmail.com
10#SBATCH --mail-type=BEGIN
11#SBATCH --mail-type=END
12#SBATCH --mail-type=FAIL
13
14module load StdEnv/2020 gcc/9.3.0 afni/23.1.08
15
16p1=/scratch/djangoc/EP_EEGfMRI_deconvolution/derivatives/freesurfer_AFNIUAC
17p2=/home/djangoc/projects/def-jgotman/djangoc/EP_EEGfMRI_deconvolution
18p3=${p2}/derivatives/afni/sub-ep0568/anat
19p5=${p2}/derivatives/afni/sub-ep0568/cavity
20p6=${p2}/derivatives/afni/sub-ep0568/events
21p7=${p2}/sub-ep0568/func
22p8=/scratch/djangoc/EP_EEGfMRI_deconvolution/derivatives/afni/sub-ep0568
23
24afni_proc.py \
25 -subj_id sub-ep0568 \
26 -out_dir ${p8}/TENT_orig_dm \
27 -script ${p8}/script/proc.sub-ep0568_TENT_orig_dm \
28 -blocks despike tshift align volreg mask blur scale \
29 regress \
30 -dsets ${p7}/sub-ep0568_task-spike_run-1_bold.nii.gz \
31 ${p7}/sub-ep0568_task-spike_run-2_bold.nii.gz \
32 ${p7}/sub-ep0568_task-spike_run-3_bold.nii.gz \
33 ${p7}/sub-ep0568_task-spike_run-4_bold.nii.gz \
34 ${p7}/sub-ep0568_task-spike_run-5_bold.nii.gz \
35 ${p7}/sub-ep0568_task-spike_run-6_bold.nii.gz \
36 ${p7}/sub-ep0568_task-spike_run-7_bold.nii.gz \
37 ${p7}/sub-ep0568_task-spike_run-8_bold.nii.gz \
38 ${p7}/sub-ep0568_task-spike_run-9_bold.nii.gz \
39 ${p7}/sub-ep0568_task-spike_run-10_bold.nii.gz \
40 -copy_anat ${p3}/anatSS.sub-ep0568.nii \
41 -anat_has_skull no \
42 -anat_follower anat_w_skull anat \
43 ${p2}/sub-ep0568/anat/sub-ep0568_T1w.nii.gz \
44 -anat_follower_ROI FS_REN_epi epi \
45 ${p1}/sub-ep0568/SUMA/aparc.a2009s+aseg_REN_all.nii.gz \
46 -anat_follower_ROI resection_25_01_2018_epi epi \
47 ${p5}/sub-ep0568_postsurgical_resection_25_01_2018_space-AFNISS.nii \
48 -anat_follower_ROI resection_23_01_2010_epi epi \
49 ${p5}/sub-ep0568_postsurgical_resection_23_01_2010_space-AFNISS.nii \
50 -tcat_remove_first_trs 3 \
51 -radial_correlate_blocks tcat volreg \
52 -volreg_align_to MIN_OUTLIER \
53 -volreg_align_e2a \
54 -align_opts_aea -check_flip -cost lpc+ZZ \
55 -giant_move -AddEdge \
56 -align_unifize_epi local \
57 -mask_epi_anat yes \
58 -mask_opts_automask -clfrac 0.1 \
59 -dilate 1 \
60 -blur_in_mask yes \
61 -blur_size 6.5 \
62 -blur_to_fwhm \
63 -regress_stim_times ${p6}/sub-ep0568_type1_dm.1D \
64 ${p6}/sub-ep0568_type2_dm.1D \
65 -regress_stim_labels type1 type2 \
66 -regress_stim_times_offset -5.25 \
67 -regress_basis 'TENT(0,25.5,18)' \
68 -regress_stim_types AM1 AM1 \
69 -regress_local_times \
70 -regress_motion_per_run \
71 -regress_censor_motion 0.5 \
72 -regress_censor_outliers 0.05 \
73 -regress_compute_fitts \
74 -regress_make_ideal_sum sum_ideal.1D \
75 -regress_est_blur_epits \
76 -regress_est_blur_errts \
77 -regress_run_clustsim yes \
78 -regress_reml_exec \
79 -regress_opts_reml -GOFORIT 99 \
80 -regress_opts_3dD -bout -jobs 16 \
81 -allzero_OK \
82 -GOFORIT 99 \
83 -regress_3dD_stop \
84 -html_review_style pythonic
85
86time tcsh -xef ${p8}/script/proc.sub-ep0568_TENT_orig_dm \
87 2>&1 | tee ${p8}/script/output.sub-ep0568_TENT_orig_dm