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…”):

    do_00_fssuma.bash

    run @SUMA_Make_Spec_FS (after FreeSurfer’s recon-all) to convert the volumetric datasets into NIFTI format and the surfaces into standardized meshes in GIFTI format

    do_01_ssw.bash

    run @SSwarper skullstripping and nonlinear warping to template space

    do_02_ap.bash

    run afni_proc.py for 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
    

Additional code availability:
The authors’ code is also available here, with additional Python scripts for generating commands on the authors’ local HPC system:

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