3dLME Comparisons

Dear AFNI Gurus,

I have a problem with my 3dLME scripts. At the individual level, I deconvolved different word types for 20 seconds after the stimulus onset, resulting in 21 beta values per word type. When I do my group level analyses with 3dLME, the results look fine at different time points individually (i.e., swear words vs. baseline is a different map for each time point, matched words vs. baseline is a different map for each time point, etc.). However, when I do contrasts, one particular contrast (swear words vs. matched words) always results in the same brain map at each time point. The contrast of swear words vs. random words (technically swear vs. two sets of random words) doesn't do this.

I've checked the individual files and they look fine for each word type, which explains why the group level word type vs. baseline results look fine too. Any thoughts on why one particular contrast would be the same for each time point at the group level? I've tried multiple different scripts with the same outcome; one example is provided below.

Thank you!

P.S. If I want to compare swear words vs. the average of the two random word groups, should I change my script to

condition : 1*swear_words -0.5*random1 -0.5*random2 timepoint : 1*0

instead of

condition : 1*swear_words -1*random1 -1*random2 timepoint : 1*0

? Similarly, when I want to average across certain time points, should it be

timepoints : 0.333*0 0.333*1 0.333*2

instead of

timepoints : 1*0 1*1 1*2

? Thank you.

3dLME script example below:

module load apptainer
apptainer exec -B "$input_dir" "$input_dir"/afni-latest_12_12_24.sif /opt/afni-latest/3dLME \
-prefix avfc_lme_analysis_w_timepoints.nii.gz \
-jobs 1 \
-mask "$input_dir"/group_mask_70percent.nii.gz \
-model "condition+age+gender+timepoint+movie" \
-qVars "age" \
-qVarCenters "26.29" \
-ranEff '~1' \
-SS_type 3 \
-num_glt 50 \
-gltLabel 1 'swear_words_time0to2' -gltCode 1 'condition : 1*swear_words timepoint : 1*0 1*1 1*2' \
-gltLabel 2 'swear_words_time3to5' -gltCode 2 'condition : 1*swear_words timepoint : 1*3 1*4 1*5' \
-gltLabel 3 'swear_words_time6to8' -gltCode 3 'condition : 1*swear_words timepoint : 1*6 1*7 1*8' \
-gltLabel 4 'swear_words_time9to11' -gltCode 4 'condition : 1*swear_words timepoint : 1*9 1*10 1*11' \
-gltLabel 5 'swear_words_time12to14' -gltCode 5 'condition : 1*swear_words timepoint : 1*12 1*13 1*14' \
-gltLabel 6 'swear_words_time15to17' -gltCode 6 'condition : 1*swear_words timepoint : 1*15 1*16 1*17' \
-gltLabel 7 'swear_words_time18to20' -gltCode 7 'condition : 1*swear_words timepoint : 1*18 1*19 1*20' \
-gltLabel 8 'swear_words_time0to8' -gltCode 8 'condition : 1*swear_words timepoint : 1*0 1*1 1*2 1*3 1*4 1*5 1*6 1*7 1*8' \
-gltLabel 9 'swear_words_time0to11' -gltCode 9 'condition : 1*swear_words timepoint : 1*0 1*1 1*2 1*3 1*4 1*5 1*6 1*7 1*8 1*9 1*10 1*11' \
-gltLabel 10 'swear_words_time0to14' -gltCode 10 'condition : 1*swear_words timepoint : 1*0 1*1 1*2 1*3 1*4 1*5 1*6 1*7 1*8 1*9 1*10 1*11 1*12 1*13 1*14' \
-gltLabel 11 'avfc_match_words_time0to2' -gltCode 11 'condition : 1*avfc_match_words timepoint : 1*0 1*1 1*2' \
-gltLabel 12 'avfc_match_words_time3to5' -gltCode 12 'condition : 1*avfc_match_words timepoint : 1*3 1*4 1*5' \
-gltLabel 13 'avfc_match_words_time6to8' -gltCode 13 'condition : 1*avfc_match_words timepoint : 1*6 1*7 1*8' \
-gltLabel 14 'avfc_match_words_time9to11' -gltCode 14 'condition : 1*avfc_match_words timepoint : 1*9 1*10 1*11' \
-gltLabel 15 'avfc_match_words_time12to14' -gltCode 15 'condition : 1*avfc_match_words timepoint : 1*12 1*13 1*14' \
-gltLabel 16 'avfc_match_words_time15to17' -gltCode 16 'condition : 1*avfc_match_words timepoint : 1*15 1*16 1*17' \
-gltLabel 17 'avfc_match_words_time18to20' -gltCode 17 'condition : 1*avfc_match_words timepoint : 1*18 1*19 1*20' \
-gltLabel 18 'avfc_match_words_time0to8' -gltCode 18 'condition : 1*avfc_match_words timepoint : 1*0 1*1 1*2 1*3 1*4 1*5 1*6 1*7 1*8' \
-gltLabel 19 'avfc_match_words_time0to11' -gltCode 19 'condition : 1*avfc_match_words timepoint : 1*0 1*1 1*2 1*3 1*4 1*5 1*6 1*7 1*8 1*9 1*10 1*11' \
-gltLabel 20 'avfc_match_words_time0to14' -gltCode 20 'condition : 1*avfc_match_words timepoint : 1*0 1*1 1*2 1*3 1*4 1*5 1*6 1*7 1*8 1*9 1*10 1*11 1*12 1*13 1*14' \
-gltLabel 21 'random_time0to2' -gltCode 21 'condition : 1*random1 1*random2 timepoint : 1*0 1*1 1*2' \
-gltLabel 22 'random_time3to5' -gltCode 22 'condition : 1*random1 1*random2 timepoint : 1*3 1*4 1*5' \
-gltLabel 23 'random_time6to8' -gltCode 23 'condition : 1*random1 1*random2 timepoint : 1*6 1*7 1*8' \
-gltLabel 24 'random_time9to11' -gltCode 24 'condition : 1*random1 1*random2 timepoint : 1*9 1*10 1*11' \
-gltLabel 25 'random_time12to14' -gltCode 25 'condition : 1*random1 1*random2 timepoint : 1*12 1*13 1*14' \
-gltLabel 26 'random_time15to17' -gltCode 26 'condition : 1*random1 1*random2 timepoint : 1*15 1*16 1*17' \
-gltLabel 27 'random_time18to20' -gltCode 27 'condition : 1*random1 1*random2 timepoint : 1*18 1*19 1*20' \
-gltLabel 28 'random_time0to8' -gltCode 28 'condition : 1*random1 1*random2 timepoint : 1*0 1*1 1*2 1*3 1*4 1*5 1*6 1*7 1*8' \
-gltLabel 29 'random_time0to11' -gltCode 29 'condition : 1*random1 1*random2 timepoint : 1*0 1*1 1*2 1*3 1*4 1*5 1*6 1*7 1*8 1*9 1*10 1*11' \
-gltLabel 30 'random_time0to14' -gltCode 30 'condition : 1*random1 1*random2 timepoint : 1*0 1*1 1*2 1*3 1*4 1*5 1*6 1*7 1*8 1*9 1*10 1*11 1*12 1*13 1*14' \
-gltLabel 31 'swear_v_random_time0to2' -gltCode 31 'condition : 1*swear_words -1*random1 -1*random2 timepoint : 1*0 1*1 1*2' \
-gltLabel 32 'swear_v_random_time3to5' -gltCode 32 'condition : 1*swear_words -1*random1 -1*random2 timepoint : 1*3 1*4 1*5' \
-gltLabel 33 'swear_v_random_time6to8' -gltCode 33 'condition : 1*swear_words -1*random1 -1*random2 timepoint : 1*6 1*7 1*8' \
-gltLabel 34 'swear_v_random_time9to11' -gltCode 34 'condition : 1*swear_words -1*random1 -1*random2 timepoint : 1*9 1*10 1*11' \
-gltLabel 35 'swear_v_random_time12to14' -gltCode 35 'condition : 1*swear_words -1*random1 -1*random2 timepoint : 1*12 1*13 1*14' \
-gltLabel 36 'swear_v_random_time15to17' -gltCode 36 'condition : 1*swear_words -1*random1 -1*random2 timepoint : 1*15 1*16 1*17' \
-gltLabel 37 'swear_v_random_time18to20' -gltCode 37 'condition : 1*swear_words -1*random1 -1*random2 timepoint : 1*18 1*19 1*20' \
-gltLabel 38 'swear_v_random_time0to8' -gltCode 38 'condition : 1*swear_words -1*random1 -1*random2 timepoint : 1*0 1*1 1*2 1*3 1*4 1*5 1*6 1*7 1*8' \
-gltLabel 39 'swear_v_random_time0to11' -gltCode 39 'condition : 1*swear_words -1*random1 -1*random2 timepoint : 1*0 1*1 1*2 1*3 1*4 1*5 1*6 1*7 1*8 1*9 1*10 1*11' \
-gltLabel 40 'swear_v_random_time0to14' -gltCode 40 'condition : 1*swear_words -1*random1 -1*random2 timepoint : 1*0 1*1 1*2 1*3 1*4 1*5 1*6 1*7 1*8 1*9 1*10 1*11 1*12 1*13 1*14' \
-gltLabel 41 'swear_v_match_words_time0to2' -gltCode 41 'condition : 1*swear_words -1*avfc_match_words timepoint : 1*0 1*1 1*2' \
-gltLabel 42 'swear_v_match_words_time3to5' -gltCode 42 'condition : 1*swear_words -1*avfc_match_words timepoint : 1*3 1*4 1*5' \
-gltLabel 43 'swear_v_match_words_time6to8' -gltCode 43 'condition : 1*swear_words -1*avfc_match_words timepoint : 1*6 1*7 1*8' \
-gltLabel 44 'swear_v_match_words_time9to11' -gltCode 44 'condition : 1*swear_words -1*avfc_match_words timepoint : 1*9 1*10 1*11' \
-gltLabel 45 'swear_v_match_words_time12to14' -gltCode 45 'condition : 1*swear_words -1*avfc_match_words timepoint : 1*12 1*13 1*14' \
-gltLabel 46 'swear_v_match_words_time15to17' -gltCode 46 'condition : 1*swear_words -1*avfc_match_words timepoint : 1*15 1*16 1*17' \
-gltLabel 47 'swear_v_match_words_time18to20' -gltCode 47 'condition : 1*swear_words -1*avfc_match_words timepoint : 1*18 1*19 1*20' \
-gltLabel 48 'swear_v_match_words_time0to8' -gltCode 48 'condition : 1*swear_words -1*avfc_match_words timepoint : 1*0 1*1 1*2 1*3 1*4 1*5 1*6 1*7 1*8' \
-gltLabel 49 'swear_v_match_words_time0to11' -gltCode 49 'condition : 1*swear_words -1*avfc_match_words timepoint : 1*0 1*1 1*2 1*3 1*4 1*5 1*6 1*7 1*8 1*9 1*10 1*11' \
-gltLabel 50 'swear_v_match_words_time0to14' -gltCode 50 'condition : 1*swear_words -1*avfc_match_words timepoint : 1*0 1*1 1*2 1*3 1*4 1*5 1*6 1*7 1*8 1*9 1*10 1*11 1*12 1*13 1*14' \
-dataTable \
Subj condition age gender movie timepoint InputFile \
1 swear_words 23 M 1 0 sub-1_500daysofsummer_"$file".nii.gz['swear_words#0_Coef'] \
1 swear_words 23 M 1 1 sub-1_500daysofsummer_"$file".nii.gz['swear_words#1_Coef'] \
1 swear_words 23 M 1 2 sub-1_500daysofsummer_"$file".nii.gz['swear_words#2_Coef'] \
1 swear_words 23 M 1 3 sub-1_500daysofsummer_"$file".nii.gz['swear_words#3_Coef'] \
1 swear_words 23 M 1 4 sub-1_500daysofsummer_"$file".nii.gz['swear_words#4_Coef'] \
1 swear_words 23 M 1 5 sub-1_500daysofsummer_"$file".nii.gz['swear_words#5_Coef'] \
1 swear_words 23 M 1 6 sub-1_500daysofsummer_"$file".nii.gz['swear_words#6_Coef'] \
1 swear_words 23 M 1 7 sub-1_500daysofsummer_"$file".nii.gz['swear_words#7_Coef'] \
1 swear_words 23 M 1 8 sub-1_500daysofsummer_"$file".nii.gz['swear_words#8_Coef'] \
1 swear_words 23 M 1 9 sub-1_500daysofsummer_"$file".nii.gz['swear_words#9_Coef'] \
1 swear_words 23 M 1 10 sub-1_500daysofsummer_"$file".nii.gz['swear_words#10_Coef'] \
1 swear_words 23 M 1 11 sub-1_500daysofsummer_"$file".nii.gz['swear_words#11_Coef'] \
1 swear_words 23 M 1 12 sub-1_500daysofsummer_"$file".nii.gz['swear_words#12_Coef'] \
1 swear_words 23 M 1 13 sub-1_500daysofsummer_"$file".nii.gz['swear_words#13_Coef'] \
1 swear_words 23 M 1 14 sub-1_500daysofsummer_"$file".nii.gz['swear_words#14_Coef'] \
1 swear_words 23 M 1 15 sub-1_500daysofsummer_"$file".nii.gz['swear_words#15_Coef'] \
1 swear_words 23 M 1 16 sub-1_500daysofsummer_"$file".nii.gz['swear_words#16_Coef'] \
1 swear_words 23 M 1 17 sub-1_500daysofsummer_"$file".nii.gz['swear_words#17_Coef'] \
1 swear_words 23 M 1 18 sub-1_500daysofsummer_"$file".nii.gz['swear_words#18_Coef'] \
1 swear_words 23 M 1 19 sub-1_500daysofsummer_"$file".nii.gz['swear_words#19_Coef'] \
1 swear_words 23 M 1 20 sub-1_500daysofsummer_"$file".nii.gz['swear_words#20_Coef'] \
1 avfc_match_words 23 M 1 0 sub-1_500daysofsummer_"$file".nii.gz['avfc_match_words#0_Coef'] \
1 avfc_match_words 23 M 1 1 sub-1_500daysofsummer_"$file".nii.gz['avfc_match_words#1_Coef'] \
1 avfc_match_words 23 M 1 2 sub-1_500daysofsummer_"$file".nii.gz['avfc_match_words#2_Coef'] \
1 avfc_match_words 23 M 1 3 sub-1_500daysofsummer_"$file".nii.gz['avfc_match_words#3_Coef'] \
1 avfc_match_words 23 M 1 4 sub-1_500daysofsummer_"$file".nii.gz['avfc_match_words#4_Coef'] \
1 avfc_match_words 23 M 1 5 sub-1_500daysofsummer_"$file".nii.gz['avfc_match_words#5_Coef'] \
1 avfc_match_words 23 M 1 6 sub-1_500daysofsummer_"$file".nii.gz['avfc_match_words#6_Coef'] \
1 avfc_match_words 23 M 1 7 sub-1_500daysofsummer_"$file".nii.gz['avfc_match_words#7_Coef'] \
1 avfc_match_words 23 M 1 8 sub-1_500daysofsummer_"$file".nii.gz['avfc_match_words#8_Coef'] \
1 avfc_match_words 23 M 1 9 sub-1_500daysofsummer_"$file".nii.gz['avfc_match_words#9_Coef'] \
1 avfc_match_words 23 M 1 10 sub-1_500daysofsummer_"$file".nii.gz['avfc_match_words#10_Coef'] \
1 avfc_match_words 23 M 1 11 sub-1_500daysofsummer_"$file".nii.gz['avfc_match_words#11_Coef'] \
1 avfc_match_words 23 M 1 12 sub-1_500daysofsummer_"$file".nii.gz['avfc_match_words#12_Coef'] \
1 avfc_match_words 23 M 1 13 sub-1_500daysofsummer_"$file".nii.gz['avfc_match_words#13_Coef'] \
1 avfc_match_words 23 M 1 14 sub-1_500daysofsummer_"$file".nii.gz['avfc_match_words#14_Coef'] \
1 avfc_match_words 23 M 1 15 sub-1_500daysofsummer_"$file".nii.gz['avfc_match_words#15_Coef'] \
1 avfc_match_words 23 M 1 16 sub-1_500daysofsummer_"$file".nii.gz['avfc_match_words#16_Coef'] \
1 avfc_match_words 23 M 1 17 sub-1_500daysofsummer_"$file".nii.gz['avfc_match_words#17_Coef'] \
1 avfc_match_words 23 M 1 18 sub-1_500daysofsummer_"$file".nii.gz['avfc_match_words#18_Coef'] \
1 avfc_match_words 23 M 1 19 sub-1_500daysofsummer_"$file".nii.gz['avfc_match_words#19_Coef'] \
1 avfc_match_words 23 M 1 20 sub-1_500daysofsummer_"$file".nii.gz['avfc_match_words#20_Coef'] \
1 random1 23 M 1 0 sub-1_500daysofsummer_"$file".nii.gz['random1#0_Coef'] \
1 random1 23 M 1 1 sub-1_500daysofsummer_"$file".nii.gz['random1#1_Coef'] \
1 random1 23 M 1 2 sub-1_500daysofsummer_"$file".nii.gz['random1#2_Coef'] \
1 random1 23 M 1 3 sub-1_500daysofsummer_"$file".nii.gz['random1#3_Coef'] \
1 random1 23 M 1 4 sub-1_500daysofsummer_"$file".nii.gz['random1#4_Coef'] \
1 random1 23 M 1 5 sub-1_500daysofsummer_"$file".nii.gz['random1#5_Coef'] \
1 random1 23 M 1 6 sub-1_500daysofsummer_"$file".nii.gz['random1#6_Coef'] \
1 random1 23 M 1 7 sub-1_500daysofsummer_"$file".nii.gz['random1#7_Coef'] \
1 random1 23 M 1 8 sub-1_500daysofsummer_"$file".nii.gz['random1#8_Coef'] \
1 random1 23 M 1 9 sub-1_500daysofsummer_"$file".nii.gz['random1#9_Coef'] \
1 random1 23 M 1 10 sub-1_500daysofsummer_"$file".nii.gz['random1#10_Coef'] \
1 random1 23 M 1 11 sub-1_500daysofsummer_"$file".nii.gz['random1#11_Coef'] \
1 random1 23 M 1 12 sub-1_500daysofsummer_"$file".nii.gz['random1#12_Coef'] \
1 random1 23 M 1 13 sub-1_500daysofsummer_"$file".nii.gz['random1#13_Coef'] \
1 random1 23 M 1 14 sub-1_500daysofsummer_"$file".nii.gz['random1#14_Coef'] \
1 random1 23 M 1 15 sub-1_500daysofsummer_"$file".nii.gz['random1#15_Coef'] \
1 random1 23 M 1 16 sub-1_500daysofsummer_"$file".nii.gz['random1#16_Coef'] \
1 random1 23 M 1 17 sub-1_500daysofsummer_"$file".nii.gz['random1#17_Coef'] \
1 random1 23 M 1 18 sub-1_500daysofsummer_"$file".nii.gz['random1#18_Coef'] \
1 random1 23 M 1 19 sub-1_500daysofsummer_"$file".nii.gz['random1#19_Coef'] \
1 random1 23 M 1 20 sub-1_500daysofsummer_"$file".nii.gz['random1#20_Coef'] \
1 random2 23 M 1 0 sub-1_500daysofsummer_"$file".nii.gz['random2#0_Coef'] \
1 random2 23 M 1 1 sub-1_500daysofsummer_"$file".nii.gz['random2#1_Coef'] \
1 random2 23 M 1 2 sub-1_500daysofsummer_"$file".nii.gz['random2#2_Coef'] \
1 random2 23 M 1 3 sub-1_500daysofsummer_"$file".nii.gz['random2#3_Coef'] \
1 random2 23 M 1 4 sub-1_500daysofsummer_"$file".nii.gz['random2#4_Coef'] \
1 random2 23 M 1 5 sub-1_500daysofsummer_"$file".nii.gz['random2#5_Coef'] \
1 random2 23 M 1 6 sub-1_500daysofsummer_"$file".nii.gz['random2#6_Coef'] \
1 random2 23 M 1 7 sub-1_500daysofsummer_"$file".nii.gz['random2#7_Coef'] \
1 random2 23 M 1 8 sub-1_500daysofsummer_"$file".nii.gz['random2#8_Coef'] \
1 random2 23 M 1 9 sub-1_500daysofsummer_"$file".nii.gz['random2#9_Coef'] \
1 random2 23 M 1 10 sub-1_500daysofsummer_"$file".nii.gz['random2#10_Coef'] \
1 random2 23 M 1 11 sub-1_500daysofsummer_"$file".nii.gz['random2#11_Coef'] \
1 random2 23 M 1 12 sub-1_500daysofsummer_"$file".nii.gz['random2#12_Coef'] \
1 random2 23 M 1 13 sub-1_500daysofsummer_"$file".nii.gz['random2#13_Coef'] \
1 random2 23 M 1 14 sub-1_500daysofsummer_"$file".nii.gz['random2#14_Coef'] \
1 random2 23 M 1 15 sub-1_500daysofsummer_"$file".nii.gz['random2#15_Coef'] \
1 random2 23 M 1 16 sub-1_500daysofsummer_"$file".nii.gz['random2#16_Coef'] \
1 random2 23 M 1 17 sub-1_500daysofsummer_"$file".nii.gz['random2#17_Coef'] \
1 random2 23 M 1 18 sub-1_500daysofsummer_"$file".nii.gz['random2#18_Coef'] \
1 random2 23 M 1 19 sub-1_500daysofsummer_"$file".nii.gz['random2#19_Coef'] \
1 random2 23 M 1 20 sub-1_500daysofsummer_"$file".nii.gz['random2#20_Coef'] \
1 other_words 23 M 1 0 sub-1_500daysofsummer_"$file".nii.gz['other_words#0_Coef'] \
1 other_words 23 M 1 1 sub-1_500daysofsummer_"$file".nii.gz['other_words#1_Coef'] \
1 other_words 23 M 1 2 sub-1_500daysofsummer_"$file".nii.gz['other_words#2_Coef'] \
1 other_words 23 M 1 3 sub-1_500daysofsummer_"$file".nii.gz['other_words#3_Coef'] \
1 other_words 23 M 1 4 sub-1_500daysofsummer_"$file".nii.gz['other_words#4_Coef'] \
1 other_words 23 M 1 5 sub-1_500daysofsummer_"$file".nii.gz['other_words#5_Coef'] \
1 other_words 23 M 1 6 sub-1_500daysofsummer_"$file".nii.gz['other_words#6_Coef'] \
1 other_words 23 M 1 7 sub-1_500daysofsummer_"$file".nii.gz['other_words#7_Coef'] \
1 other_words 23 M 1 8 sub-1_500daysofsummer_"$file".nii.gz['other_words#8_Coef'] \
1 other_words 23 M 1 9 sub-1_500daysofsummer_"$file".nii.gz['other_words#9_Coef'] \
1 other_words 23 M 1 10 sub-1_500daysofsummer_"$file".nii.gz['other_words#10_Coef'] \
1 other_words 23 M 1 11 sub-1_500daysofsummer_"$file".nii.gz['other_words#11_Coef'] \
1 other_words 23 M 1 12 sub-1_500daysofsummer_"$file".nii.gz['other_words#12_Coef'] \
1 other_words 23 M 1 13 sub-1_500daysofsummer_"$file".nii.gz['other_words#13_Coef'] \
1 other_words 23 M 1 14 sub-1_500daysofsummer_"$file".nii.gz['other_words#14_Coef'] \
1 other_words 23 M 1 15 sub-1_500daysofsummer_"$file".nii.gz['other_words#15_Coef'] \
1 other_words 23 M 1 16 sub-1_500daysofsummer_"$file".nii.gz['other_words#16_Coef'] \
1 other_words 23 M 1 17 sub-1_500daysofsummer_"$file".nii.gz['other_words#17_Coef'] \
1 other_words 23 M 1 18 sub-1_500daysofsummer_"$file".nii.gz['other_words#18_Coef'] \
1 other_words 23 M 1 19 sub-1_500daysofsummer_"$file".nii.gz['other_words#19_Coef'] \
1 other_words 23 M 1 20 sub-1_500daysofsummer_"$file".nii.gz['other_words#20_Coef'] \
2 swear_words 25 F 1 0 sub-2_500daysofsummer_"$file".nii.gz['swear_words#0_Coef'] \
2 swear_words 25 F 1 1 sub-2_500daysofsummer_"$file".nii.gz['swear_words#1_Coef'] \
etc...

I assume that condition is a within-individual factor. Is movie a within- or between-individual factor?

Gang Chen

Hi Gang,
That's right. Condition is within-individual, and movie is between-individual.
Thanks!

To more accurately capture differences in the hemodynamic response between the two conditions, I recommend using the following model specification with 3dLMEr instead of 3dLME:

3dLMEr \
...
-model "condition*timepoint + age + gender + movie" \
...

In the output, the interaction term condition:timepoint primarily reflects the differential hemodynamic response between the two conditions.

Alternatively, you may consider using 3dMSS, as described in this AFNI blog post and the associated paper, which focuses on enhancing sensitivity to HDR differences through profile estimation.

Gang Chen

Thank you for these suggestions; I will work on implementing this in 3dLMEr now. In the meantime, I'm wondering whether you have an idea what might be contributing to the error in the contrast for swears vs. matched in 3dLME? I'm unsure how changing the model specification to include an interaction would allow for comparison between swear vs. matched in the glts, especially since the swear vs. random comparison worked without the interaction in the model.

I'm unsure how changing the model specification to include an interaction would allow for comparison between swear vs. matched in the glts, especially since the swear vs. random comparison worked without the interaction in the model.

The issue with your original script involves two key aspects:

  • Model misspecification, and
  • Inefficient extraction of effects

The misspecified model is likely to produce misleading results, as you’ve already noticed. For a more detailed discussion on condition comparisons in the context of hemodynamic response modeling, see this paper.

Regarding contrast specification, could you elaborate on your specific research hypotheses? Once we understand the hypotheses, we can discuss the proper syntax for specifying them using -gltCode.

Gang Chen

Thank you, Gang. My hypotheses are that early responses to hearing specific types of words will occur in some brain regions, responses during the HRF peak will occur in other regions, and later responses will occur in different regions. My deconvolution included 21 beta values for 20 seconds post-stimulus onset, but the later betas (post 14 seconds) seemed to be skewing the overall results when timepoint wasn't specifically modeled (I use the post-14 betas in a different analysis, which is why I didn't cut them out at the individual level). Thus, for this paper, I'm planning to report the glt results rather than the full model results, and I focused the glts on grouping early and later timepoints in 3 second intervals, plus overall results from onset to 14 seconds post stimulus. One other thing to note is that the random group of words were done twice to account for potential bias in the selection, then the intent was to average those two groups in the glts.

Here is my script that I ran with 3dLMEr last night:

module load apptainer
apptainer exec -B "$input_dir" "$input_dir"/afni-latest_12_12_24.sif /opt/afni-latest/3dLMEr \
-prefix avfc_lmeR_analysis_w_timepoints2.nii.gz \
-jobs 1 \
-mask "$input_dir"/group_mask_70percent.nii.gz \
-model 'condition*timepoint+age+gender+movie+(1|Subj)' \
-qVars 'age' \
-qVarCenters '26.29' \
-SS_type 3 \
-gltCode swear_words_time0to2 'condition : 1*swear_words timepoint : 0.333*0 0.333*1 0.333*2' \
-gltCode swear_words_time3to5 'condition : 1*swear_words timepoint : 0.333*3 0.333*4 0.333*5' \
-gltCode swear_words_time6to8 'condition : 1*swear_words timepoint : 0.333*6 0.333*7 0.333*8' \
-gltCode swear_words_time9to11 'condition : 1*swear_words timepoint : 0.333*9 0.333*10 0.333*11' \
-gltCode swear_words_time12to14 'condition : 1*swear_words timepoint : 0.333*12 0.333*13 0.333*14' \
-gltCode swear_words_time0to14 'condition : 1*swear_words timepoint : 0.067*0 0.067*1 0.067*2 0.067*3 0.067*4 0.067*5 0.067*6 0.067*7 0.067*8 0.067*9 0.067*10 0.067*11 0.067*12 0.067*13 0.067*14' \
-gltCode avfc_match_words_time0to2 'condition : 1*avfc_match_words timepoint : 0.333*0 0.333*1 0.333*2' \
-gltCode avfc_match_words_time3to5 'condition : 1*avfc_match_words timepoint : 0.333*3 0.333*4 0.333*5' \
-gltCode avfc_match_words_time6to8 'condition : 1*avfc_match_words timepoint : 0.333*6 0.333*7 0.333*8' \
-gltCode avfc_match_words_time9to11 'condition : 1*avfc_match_words timepoint : 0.333*9 0.333*10 0.333*11' \
-gltCode avfc_match_words_time12to14 'condition : 1*avfc_match_words timepoint : 0.333*12 0.333*13 0.333*14' \
-gltCode avfc_match_words_time0to14 'condition : 1*avfc_match_words timepoint : 0.067*0 0.067*1 0.067*2 0.067*3 0.067*4 0.067*5 0.067*6 0.067*7 0.067*8 0.067*9 0.067*10 0.067*11 0.067*12 0.067*13 0.067*14' \
-gltCode random_time0to2 'condition : 0.5*random1 0.5*random2 timepoint : 0.333*0 0.333*1 0.333*2' \
-gltCode random_time3to5 'condition : 0.5*random1 0.5*random2 timepoint : 0.333*3 0.333*4 0.333*5' \
-gltCode random_time6to8 'condition : 0.5*random1 0.5*random2 timepoint : 0.333*6 0.333*7 0.333*8' \
-gltCode random_time9to11 'condition : 0.5*random1 0.5*random2 timepoint : 0.333*9 0.333*10 0.333*11' \
-gltCode random_time12to14 'condition : 0.5*random1 0.5*random2 timepoint : 0.333*12 0.333*13 0.333*14' \
-gltCode random_time0to14 'condition : 0.5*random1 0.5*random2 timepoint : 0.067*0 0.067*1 0.067*2 0.067*3 0.067*4 0.067*5 0.067*6 0.067*7 0.067*8 0.067*9 0.067*10 0.067*11 0.067*12 0.067*13 0.067*14' \
-gltCode swear_v_random_time0to2 'condition : 1*swear_words -0.5*random1 -0.5*random2 timepoint : 0.333*0 0.333*1 0.333*2' \
-gltCode swear_v_random_time3to5 'condition : 1*swear_words -0.5*random1 -0.5*random2 timepoint : 0.333*3 0.333*4 0.333*5' \
-gltCode swear_v_random_time6to8 'condition : 1*swear_words -0.5*random1 -0.5*random2 timepoint : 0.333*6 0.333*7 0.333*8' \
-gltCode swear_v_random_time9to11 'condition : 1*swear_words -0.5*random1 -0.5*random2 timepoint : 0.333*9 0.333*10 0.333*11' \
-gltCode swear_v_random_time12to14 'condition : 1*swear_words -0.5*random1 -0.5*random2 timepoint : 0.333*12 0.333*13 0.333*14' \
-gltCode swear_v_random_time0to11 'condition : 1*swear_words -0.5*random1 -0.5*random2 timepoint : 0.083*0 0.083*1 0.083*2 0.083*3 0.083*4 0.083*5 0.083*6 0.083*7 0.083*8 0.083*9 0.083*10 0.083*11' \
-gltCode swear_v_random_time0to14 'condition : 1*swear_words -0.5*random1 -0.5*random2 timepoint : 0.067*0 0.067*1 0.067*2 0.067*3 0.067*4 0.067*5 0.067*6 0.067*7 0.067*8 0.067*9 0.067*10 0.067*11 0.067*12 0.067*13 0.067*14' \
-gltCode swear_v_match_words_time0to2 'condition : 1*swear_words -1*avfc_match_words timepoint : 0.333*0 0.333*1 0.333*2' \
-gltCode swear_v_match_words_time3to5 'condition : 1*swear_words -1*avfc_match_words timepoint : 0.333*3 0.333*4 0.333*5' \
-gltCode swear_v_match_words_time6to8 'condition : 1*swear_words -1*avfc_match_words timepoint : 0.333*6 0.333*7 0.333*8' \
-gltCode swear_v_match_words_time9to11 'condition : 1*swear_words -1*avfc_match_words timepoint : 0.333*9 0.333*10 0.333*11' \
-gltCode swear_v_match_words_time12to14 'condition : 1*swear_words -1*avfc_match_words timepoint : 0.333*12 0.333*13 0.333*14' \
-gltCode swear_v_match_words_time0to14 'condition : 1*swear_words -1*avfc_match_words timepoint : 0.067*0 0.067*1 0.067*2 0.067*3 0.067*4 0.067*5 0.067*6 0.067*7 0.067*8 0.067*9 0.067*10 0.067*11 0.067*12 0.067*13 0.067*14' \
-dataTable \
Subj condition age gender movie timepoint InputFile \
...followed by same data table from before...

I added +(1|Subj) to account for the removal of -ranEff from the 3dLME program, and I adjusted the weights in the glts. Does this look reasonable to you?

I received the following error message:

Warning message:
In if (!is.na(lop$qVarCenters)) lop$qVarCenters <- as.numeric(strsplit(as.character(lop$qVarCenters),  :
  the condition has length > 1 and only the first element will be used
Loading required package: lmerTest
Loading required package: lme4
Loading required package: Matrix

Attaching package: ‘lmerTest’

The following object is masked from ‘package:lme4’:

    lmer

The following object is masked from ‘package:stats’:

    step

Loading required package: phia
Loading required package: car
Loading required package: carData
Registered S3 methods overwritten by 'car':
  method                          from
  influence.merMod                lme4
  cooks.distance.influence.merMod lme4
  dfbeta.influence.merMod         lme4
  dfbetas.influence.merMod        lme4
boundary (singular) fit: see ?isSingular
Error in apply(comArr[, , kk, ], c(1, 2), runLME, dataframe = lop$dataStr,  :
  object 'comArr' not found
Calls: aperm -> apply
Execution halted

What is your AFNI version (afni -ver)?

For your use of 3dLMEr, I recommend the following model specification:

-model 'condition*timepoint + age + gender + movie + (1|Subj) + (1|Subj:condition) + (1|Subj:timepoint)'

For more details on specifying individual-level random effects in hierarchical models, see this AFNI blog post.

Regarding effect estimation: for a contrast like this,

-gltCode swear_words_time0to2 'condition : 1*swear_words timepoint : 0.333*0 0.333*1 0.333*2'

you might consider using -glfCode instead, which may offer greater sensitivity. For example:

-glfCode swear_words_time0to2 'condition : 1*swear_words timepoint : 1*0 & condition : 1*swear_words timepoint : 1*1 & condition : 1*swear_words timepoint : 1*2'

You can apply a similar strategy to your other -gltCode specifications as well.

Gang Chen

Hi Gang,

I'm using a containerized version of AFNI, which we compiled at the end of 2024. However, the version looks to be pretty old:

Precompiled binary linux_openmp_64: Oct 19 2020 (Version AFNI_20.3.01 'Vespasian')

Do you think this is part of the issue? If so, is there a newer container version for download? Thank you.

Howdy-

We do keep updating out docker container here on dockerhub as we release AFNI versions.

We have some notes about working with Docker here, as well.

We are also in the process of updating our container creation mechanism. But if you have an existing one at present, I assume that came from the above dockerhub one.

--pt

Hi Paul,
Thank you for your help. I initially tried the afni_make_build container, but it didn't seem to have the R dependencies that I needed. I tried the afni_cmake_build container today (as a .sif file), and I'm still having some trouble. When I call 3dLMEr, I get the following error message:

** Error 3dLMEr:
3dLMEr.R not found in /opt/afni/src/src/scripts_for_r or /opt/afni/src/src/scripts_for_r/R_scripts or /opt/afni/src/../install/usr/local/bin

Fatal error: cannot open file '3dLMEr.R': No such file or directory

Looking around the directories, I see that 3dLMEr.R is actually located in /opt/afni/src/src/R_scripts, or at the same level as scripts_for_r. I believe there's probably a simple path solution for this, but I'm unsure whether I should be trying to update the path in the scripts_for_r/3dLMEr file within the .sif, or within my own environment before I run my scripts, or somewhere else. Any guidance you can offer would be much appreciated! Thank you.