Hi I’m starting to write a script to process fMRI data. I would like to use participant’s reaction time as the duration of each event. I’m coming from FSL word where I would set up a 3-column text file with onset duration and weight and so would set up the duration as the RT. I can’t find how to do the same with AFNI, could you help me figuring that out?
You are looking for what are called married regressors. Have a look at https://afni.nimh.nih.gov/pub/dist/doc/program_help/3dDeconvolve.html and search for married.
In brief, each event in a regressor will consist of onset:duration pairs, e.g., for an event that starts at T=2s and lasted 1.2s you would encode this as 2:1.2. In afni, regressors are entered in text files with one line per run and multiple events within a run separated on a line by spaces. Runs with no events are marked with a *
For example, consider a STOP signal like paradigm with 3 runs. A regressor file would look like:
2:1.2 4:1.0 5.5:0.86
*
1:0.9 10:2
So run 1 consisted or 3 events (we’re keeping it short for simplicity), run two had no STOPs, and run 3 had only 2 STOPS.
Typically, you couple these with something like dmBLOCK(1) which tells 3dDeconvole you want to duration mudulated response model where the duration is taken from the bit after the : in your regressors (i.e., the duration) and the amplitude of the response model is encoded as the ‘1’ argument to dmBLOCK. Other values are of course possible, but you have to be sure what you’re doing.
If you’ve already got an FSL compatible file with three column regressors, something like the following will do the conversion for you
reg_file=fsl_regressors.txt
find only lines ending in a 1,
pass them to awk which then prints the first element of each
line and the second element of each line separated by a :,
then convert the newlines to a space so that AFNI’s stim_times
convention of each row being a run are observed
save the results to the a file named after
the input regressors except that it has stimtimes in the middle
this is the conversion from fsl regressor files to afni regressor files, meaning that “onset duration that stimulus” becomes “onset:duration”
this grep with “1$” means get the one at the end of the file
tr means translate, takes two arguments, [set1 set2], will translate the first into the second
the %% means cut off from the end “.txt”
grep “1$” ${reg_file} |
awk ‘BEGIN {OFS=“:”} {print $1,$2}’ |
tr ‘\n’ ’ ’ > ${reg_file%%.txt}.stimtimes.txt
Oh gotcha , I was planning on using a GAM function since I used double gamma HRF in FSL and it seems to be the closest approach but I think I will use block(1) given your comment,
Thank you so much for the fast response.
AFNI’s format for stimulation times associated with duration use a colon between the time and duration. You can generate these “married” parameters with 1dMarry. afni_proc.py can take married stimulus timing files as input with options for the stim_times_type (see afni_proc.py example 7 for AM1 or AM2 stimulus timing). (3dDeconvolve’s help has information on using -stim_times_FSL to use the FSL format, but this will be harder to integrate into afni_proc.py). There are lots of options in the 3dDeconvolve help for this, searching for “duration”.
https://afni.nimh.nih.gov/pub/dist/doc/htmldoc/programs/afni_proc.py_sphx.html#example-7-apply-some-esoteric-options
https://afni.nimh.nih.gov/pub/dist/doc/htmldoc/programs/3dDeconvolve_sphx.html#ahelp-3ddeconvolve
Also see this previous posting:
https://afni.nimh.nih.gov/afni/community/board/read.php?1,168468,168469#msg-168469
Thanks so much will look into this
Hi I’m still struggling with this section, I’m getting an error specific to the 3dDeconvolve section (that I’m pasting below)
I created my txt files in the attached document (I just have one run and random timing - at the moment to debug my script )
This is the error I’m getting (I looked for this error on this board, one person has solved it by adding stim_times_AM1 but it’s in my script (see below) and does not help.
looks like I fix the error on 3Ddeconvolve, now I need to adjust it in my AFNI proc.py script
3dDeconvolve -input ${analysisdir}/pb03.$subj.r*.blur+orig.HEAD
-ortvec ${analysisdir}/mot_demean.r01.1D mot_demean_r01
-polort 3
-num_stimts 2
-stim_times_AM1 1 ${analysisdir}/stimuli/offset_congruent.stimtimes.txt ‘dmBLOCK(1)’
-stim_label 1 Congruent
-stim_times_AM1 2 ${analysisdir}/stimuli/offset_incongruent.txt ‘dmBLOCK(1)’
-stim_label 2 Incongruent
-jobs 16
-gltsym ‘SYM: +Incongruent -Congruent’
-glt_label 1 ‘Incongruent vs Congruent’
-fout -tout -x1D X.xmat.1D -xjpeg X.jpg
-x1D_uncensored X.nocensor.xmat.1D
-fitts fitts.$subj
-errts errts.${subj}
-x1D_stop
-bucket stats.$subj
ALSO placing my afniproc py script below
#!/bin/bash
#Name: Targeting.sh
Author: LB
Date: 7/12/22
Syntax: ./Targeting.sh SUBJ
Arguments: SUBJ: subject ID
Description: This script will run all chosen scans through the afni_proc.py pipeline
Requirements: 1) AFNI
Notes: –
if [ “$#” -eq 1 ]; then
subj=$1
else
echo “Specify participant ID Please”
exit 1
fi
pwd_dir=pwd
proj_dir=${pwd_dir%/*}
SETTING UP THE DIRECTORIES
anatdir=${proj_dir}/Anat/${subj}
funcdir=${proj_dir}/Func/${subj}
stimdir=${proj_dir}/Behav/${subj}
analysisdir=${proj_dir}/Analysis/${subj}
cd ${analysisdir}
DATA CHECK
#for anat
if [ -f “${anatdir}/${subj}_T1.nii” ] ; then
echo -e “\033[0;35m++ Found T1 of $subj… ++\033[0m”
else
echo -e “\033[0;35m++ This participant does not have T1 scan … EXITING ++\033[0m”
exit
fi
if [ -f “${funcdir}/${subj}_Stroop_Run01.nii” ] ; then
echo -e “\033[0;35m++ Found functional for participant ${subj}, moving to next step … ++\033[0m”
else
echo -e “\033[0;35m++ Subject $subj does not have functional scans… EXITING ++\033[0m”
exit 1
fi
SETTING UP AFNI ## need to add fixation and ITI and incorrect as stim
afni_proc.py
-subj_id ${subj}
-blocks tshift align volreg blur mask regress
-copy_anat ${anatdir}/${subj}_T1.nii
-dsets
${funcdir}/${subj}_Stroop_Run01.nii
-tcat_remove_first_trs 5
-regress_stim_times_offset -10
-align_opts_aea -cost lpc+ZZ -giant_move
-anat_uniform_method unifize
-volreg_align_to MIN_OUTLIER
-volreg_align_e2a
-regress_est_blur_errts
-blur_size 4.0
-regress_motion_per_run
-regress_censor_motion 0.3
-regress_reml_exec
-regress_3dD_stop
-regress_stim_types AM1
-regress_stim_times
${stimdir}/congruent.stimtimes.txt
${stimdir}/incongruent.txt
-regress_stim_labels Congruent Incongruent
-regress_basis ‘dmBLOCK(1)’
-regress_opts_3dD -jobs 16
-gltsym ‘SYM: Incongruent-Congruent’
-glt_label Incongruent - Congruent
-outdir ${analysisdir}
-html_review_style pythonic
-execute
Do you know what I’m doing wrong? Thank you very much in advance
So what’s the error you get?
I think it actually finally worked!!
the only thing is that it;'s using TR = 3 while my TR = 2 (see below) is there any way I can edit that?
++ STAT automask has 46932 voxels (out of 411825 = 11.4%)
++ Skipping check for initial transients
++ Input polort=3; Longest run=405.0 s; Recommended minimum polort=3 ++ OK ++
++ -stim_times using TR=3 s for stimulus timing conversion
++ -stim_times using TR=3 s for any -iresp output datasets
++ [you can alter the -iresp TR via the -TR_times option]
++ ** -stim_times NOTE ** guessing GLOBAL times if 1 time per line; LOCAL otherwise
++ ** GUESSED ** -stim_times_AM1 1 using LOCAL times
++ ** GUESSED ** -stim_times_AM1 2 using LOCAL times
GLT matrix from ‘SYM: +Incongruent -Congruent’:
0 0 0 0 -1 1 0 0 0 0 0 0
++ Number of time points: 135 (no censoring)
- Number of parameters: 12 [10 baseline ; 2 signal]
++ total shared memory needed = 16,473,000 bytes (about 16 million)
++ mmap() memory allocated: 16,473,000 bytes (about 16 million)
++ Memory required for output bricks = 16,473,000 bytes (about 16 million)
++ Wrote matrix image to file X.jpg
++ Wrote matrix values to file X.xmat.1D
Check that the TR is correct in the input EPI volume(s), in this case ${funcdir}/${subj}_Stroop_Run01.nii
3dinfo ${funcdir}/${subj}_Stroop_Run01.nii
you can get lots more info (more than you need to check the TR) by instead running
3dinfo -verb ${funcdir}/${subj}_Stroop_Run01.nii