Custom Slice-Timing Correction

AFNI version info (afni -ver): Version AFNI_24.1.00 'Publius Septimius Geta'

Hello, I'm a beginner so apologies in advance if I'm missing helpful information.

I have multiband EPIs, 60 slices, with groups of six slices acquired simultaneously (TR = 0.8s):

 1  11  21  31  41  51 @ 0 ~ 80 ms
 3  13  23  33  43  53 @ 80 ~160 ms
 5  15  25  35  45  55 @ 160~240 ms
10  20  30  40  50  60 @ 240~320 ms 
 8  18  28  38  48  58 @ 320~400 ms
 6  16  26  36  46  56 @ 400~480 ms
 2  12  22  32  42  52 @ 480~ 560 ms
 4  14  24  34  44  54  @ 560~640 ms
 9  19  29  39  49  59 @ 640~720 ms
 7  17  27  37  47  57 @ 720~800 ms

3dinfo -slice_timing returns a series of 60 0s, so the slice timings are not in the data itself.

I adapted afni_proc.py to include a custom list of slice timings:
-tshift_opts_ts -tpattern @${top_dir}proc_rs/slice_timings.txt

slice_timings.txt being:
0
480
80
560
160
400
720
320
640
240
(etc, repeated 6 times for all 60 slices)

However, for the output I'm getting the following error:
** FATAL ERROR: Illegal value 480 in tpattern file /project2/skeedy/FC/FC_133/proc_rs/slice_timings.txt
** Program compile date = Apr 2 2024

Here's most of the 3dinfo output for the resting-state EPI:

Identifier Code: AFN_V0hoJRmNcp9kPvIAv5QYBg Creation Date: Mon Jul 8 14:44:47 2024
Template Space: ORIG
Dataset Type: Echo Planar (-epan)
Byte Order: LSB_FIRST {assumed} [this CPU native = LSB_FIRST]
Storage Mode: NIFTI
Storage Space: 663,552,000 (664 million) bytes
Geometry String: "MATRIX(2.21875,0,0,-105.9918,0,-2.21875,0,96.97379,0,0,2.399998,-65.28899):96,96,60"
Data Axes Tilt: Plumb
Data Axes Orientation:
first (x) = Right-to-Left
second (y) = Posterior-to-Anterior
third (z) = Inferior-to-Superior [-orient RPI]
R-to-L extent: -105.992 [R] -to- 104.789 [L] -step- 2.219 mm [ 96 voxels]
A-to-P extent: -113.807 [A] -to- 96.974 [P] -step- 2.219 mm [ 96 voxels]
I-to-S extent: -65.289 [I] -to- 76.311 [S] -step- 2.400 mm [ 60 voxels]
Number of time steps = 600 Time step = 0.80000s Origin = 0.00000s
-- At sub-brick #0 '?' datum type is short [*12.0244]
-- At sub-brick #1 '?' datum type is short [*12.0244]
-- At sub-brick #2 '?' datum type is short [*12.0244]
** For info on all 600 sub-bricks, use '3dinfo -verb' **

And the full afni_proc.py script if it helps:

# set data directories
set top_dir = /project2/skeedy/FC/"${subj}"
set anat_dir  = "${top_dir}/nlWarp/${subj_num_only}_anatWarped"
set epi_dir   = "${top_dir}"

# run afni_proc.py to create a single subject processing script
afni_proc.py -subj_id "${subj}"                                                  \
        -script proc."${subj}.rs" -scr_overwrite                                     \
        -blocks despike tshift align tlrc volreg blur mask scale regress      \
        -copy_anat ${anat_dir}/anatSS.${subj_num_only}.nii                               \
        -anat_has_skull no                                                    \
        -dsets                                                                \
            ${epi_dir}/*REST*.nii.gz                                     \
        -tshift_opts_ts -tpattern @${top_dir}slice_timings.txt                                     \
        -tlrc_base ${top_dir}/nlWarp/MNI152_2009_template_SSW.nii.gz            \
        -tlrc_NL_warp                                                         \
        -tlrc_NL_warped_dsets                                                 \
            ${anat_dir}/anatQQ.${subj_num_only}.nii                                      \
            ${anat_dir}/anatQQ.${subj_num_only}.aff12.1D                                 \
            ${anat_dir}/anatQQ.${subj_num_only}_WARP.nii                                 \
        -volreg_align_to MIN_OUTLIER                                          \
        -volreg_align_e2a                                                     \
        -volreg_tlrc_warp                                                     \
        -blur_size 4.0                                                        \
        -mask_segment_anat yes                                                \
        -mask_segment_erode yes                                               \
        -mask_rm_segsy no                                                     \
        -regress_censor_motion 0.2                                            \
        -regress_censor_outliers 0.05                                         \
        -regress_apply_mot_types demean deriv                                 \
        -regress_ROI WMe                                                      \
        -regress_est_blur_epits                                               \
        -regress_est_blur_errts

end

Thank you, I really appreciate the help!

UPDATE:

I found this and I'm using 3drefit as instructed here:

After the edit, it looks correct:

3dinfo -slice_timing modified_rest.nii.gz
0.000000|480.000000|80.000000|560.000000|160.000000|400.000000|720.000000|320.000000|640.000000|240.000000|0.000000|480.000000|80.000000|560.000000|160.000000|400.000000|720.000000|320.000000|640.000000|240.000000|0.000000|480.000000|80.000000|560.000000|160.000000|400.000000|720.000000|320.000000|640.000000|240.000000|0.000000|480.000000|80.000000|560.000000|160.000000|400.000000|720.000000|320.000000|640.000000|240.000000|0.000000|480.000000|80.000000|560.000000|160.000000|400.000000|720.000000|320.000000|640.000000|240.000000|0.000000|480.000000|80.000000|560.000000|160.000000|400.000000|720.000000|320.000000|640.000000|240.000000

Does this mean I should entirely remove this line from afni_proc.py?
-tshift_opts_ts -tpattern @${top_dir}/proc_rs/slice_timings.txt \

When I do remove it, the output area that showed the error is now:

++ FINAL: 300488400 data points, 17225986 edits [5.733%], 4792441 big edits [1.595%]
++ Output dataset ./pb01.FC_133.r01.despike+orig.BRIK
end
foreach run ( 01 )
3dTshift -tzero 0 -quintic -prefix pb02.FC_133.r01.tshift pb01.FC_133.r01.despike+orig
++ 3dTshift: AFNI version=AFNI_24.1.00 (Apr 2 2024) [64-bit]
*+ WARNING: some value in tpattern is outside range 0..TR=0.8
*+ WARNING: ==>> output dataset is just a copy of input dataset
end

And the out.ss_review.txt:

subject ID : FC_133
AFNI version : AFNI_24.1.00
AFNI package : linux_openmp_64
TR : 0.8
TRs removed (per run) : 0
multiband level : 6
slice timing pattern : irregular
num stim classes provided : 0
final anatomy dset : anat_final.FC_133+tlrc.HEAD
final stats dset : NO_STATS
final errts dset : errts.FC_133.tproject+tlrc.HEAD
orig voxel counts : 96 96 60
orig voxel resolution : 2.218750 2.218750 2.399998
orig volume center : -0.601173 -8.416832 5.510956
final voxel resolution : 2.000000 2.000000 2.000000

motion limit : 0.2
num TRs above mot limit : 160
average motion (per TR) : 0.152898
average censored motion : 0.112106
max motion displacement : 1.83504
max censored displacement : 1.7184
outlier limit : 0.05
average outlier frac (TR) : 0.0021523
num TRs above out limit : 4

num runs found : 1
num TRs per run : 600
num TRs per run (applied) : 318
num TRs per run (censored): 282
fraction censored per run : 0.47
TRs total (uncensored) : 600
TRs total : 318
degrees of freedom used : 18
degrees of freedom left : 300
final DF fraction : 0.5

TRs censored : 282
censor fraction : 0.470000
num regs of interest : 0

TSNR average : 114
global correlation (GCOR) : 0.0245001
anat/EPI mask Dice coef : 0.906394
anat/templ mask Dice coef : 0.995191
blur estimates (ACF) : 0.829856 2.94972 11.2878
blur estimates (FWHM) : 0 0 0

Is this the correct approach for slice-timing correction?

I think you forgot to add the scale factor in the 3drefit command to convert from ms to seconds.

3drefit -Tslices '*0.001'  ...

That's why the 3dTshift command says the values are larger than the TR and doesn't apply the values. Alternatively, scale the values to seconds separately.

Thank you--that took care of the error. Just to confirm, after the 3drefit edit, there is no longer a need for this tshift_opts_ts line from afni_proc.py, correct?

-tshift_opts_ts -tpattern @${top_dir}/proc_rs/slice_timings.txt \

Even after it is removed, it looks like full, generated proc script still performs slice-timing corrections:

# time shift data so all slice timing is the same
foreach run ( $runs )
    3dTshift -tzero 0 -quintic -prefix pb02.$subj.r$run.tshift \
             pb01.$subj.r$run.despike+orig
end

Here's the output after removal and your 3drefit correction. It still recognizes the data as multiband with an irregular slice-timing pattern. So it looks like all is well now--thank you again.

subject ID                : FC_133
AFNI version              : AFNI_24.1.00
AFNI package              : linux_openmp_64
TR                        : 0.8
TRs removed (per run)     : 0
multiband level           : 6
slice timing pattern      : irregular
num stim classes provided : 0
final anatomy dset        : anat_final.FC_133+tlrc.HEAD
final stats dset          : NO_STATS
final errts dset          : errts.FC_133.tproject+tlrc.HEAD
orig voxel counts         : 96  96      60
orig voxel resolution     : 2.218750    2.218750        2.399998
orig volume center        : -0.601173   -8.416832       5.510956
final voxel resolution    : 2.000000    2.000000        2.000000

motion limit              : 0.2
num TRs above mot limit   : 123
average motion (per TR)   : 0.139386
average censored motion   : 0.11541
max motion displacement   : 1.8428
max censored displacement : 1.75809
outlier limit             : 0.05
average outlier frac (TR) : 0.0021523
num TRs above out limit   : 4

num runs found            : 1
num TRs per run           : 600
num TRs per run (applied) : 376
num TRs per run (censored): 224
fraction censored per run : 0.373333
TRs total (uncensored)    : 600
TRs total                 : 376
degrees of freedom used   : 18
degrees of freedom left   : 358
final DF fraction         : 0.596667

TRs censored              : 224
censor fraction           : 0.373333
num regs of interest      : 0

TSNR average              : 124.356
global correlation (GCOR) : 0.0233834
anat/EPI mask Dice coef   : 0.906661
anat/templ mask Dice coef : 0.995191
blur estimates (ACF)      : 0.825688 2.95074 11.4316
blur estimates (FWHM)     : 0 0 0
1 Like