a possible bug in afni_proc.py

Hi,
I was recently trying to adapt Example 11 of the documentation of afni_proc.py for my project.
The command is as below:
afni_proc.py -out_dir $subj.results -subj_id $subj -blocks despike tshift align tlrc volreg mask scale regress
-script $subj/proc.$subj.test -scr_overwrite
-radial_correlate_blocks volreg
-copy_anat $fs_dir/brain.finalsurfs.nii.gz
-anat_has_skull no
-anat_follower anat_w_skull anat $fs_dir/${subj}_SurfVol.nii
-anat_follower_ROI aaseg anat $fs_dir/aparc.a2009s+aseg.nii.gz
-anat_follower_ROI aeseg epi $fs_dir/aparc.a2009s+aseg.nii.gz
-anat_follower_ROI aaseggm anat $fs_dir/aparc.a2009s+aseg_REN_gmrois.nii.gz
-anat_follower_ROI aeseggm epi $fs_dir/aparc.a2009s+aseg_REN_gmrois.nii.gz
-anat_follower_ROI FSvent epi $fs_dir/aparc.a2009s+aseg_REN_vent.nii.gz
-anat_follower_ROI FSwmat epi $fs_dir/aparc.a2009s+aseg_REN_wmat.nii.gz
-anat_follower_erode FSvent FSwmat
-dsets $str_dsets
-tshift_opts_ts -tpattern @$all_out_dir/…/slice_timing.txt
-align_opts_aea -cost lpc+ZZ -giant_move -check_flip
-tlrc_base MNI152_2009_template_SSW.nii.gz
-tlrc_NL_warp
-volreg_align_to MIN_OUTLIER
-volreg_post_vr_allin yes
-volreg_pvra_base_index MIN_OUTLIER
-volreg_align_e2a
-mask_epi_anat yes
-regress_motion_per_run
-regress_ROI_PC FSvent 3
-regress_ROI_PC FSwmat 3
-regress_ROI_PC_per_run FSvent FSwmat
-regress_make_corr_vols aeseggm FSvent
-regress_apply_mot_types demean deriv
-html_review_style pythonic

The major change is that I removed the -volreg_tlrc_warp option because I wanted to analyze the data in the subject space. fs_dir is my freesurfer SUMA folder generated by @SUMA_Make_Spec_FS command because I wanted to utilize the skull stripping and atlas created by freesurfer.
When the script failed for some reason, I got the chance to look at the information of some files that are supposed to be removed (and I verified the following in the generated script). What I noticed is that the script applied the warping of -nwarp anat.un.aff.qw_WARP.nii anat.un.aff.Xat.1D to the ventricle and white matter masks from freesurfer. I believe this is the warping that can put the subject’s brain into MNI template. Then the script left these resulting files such as follow_ROI_FSwmat in the original space even though they should be in tlrc space. And then this warped mask was used to extract PCA components which were in turn used to denoise data. I can visually verify that the follow_ROI_FSwmat+orig does not match the actual regions of white matter in the EPI data because of the above steps.

My guess is that the approach above would work if a user chooses to analyze the data in tlrc space, but when a user chooses not to warp EPI data to tlrc space, then it can use the wrong mask. I think in my case, the ROI resampled directly from freesurfer should be used instead.
Of course, you may say that the user should not use the options of -anat_follower_ROI in this case because it is simply unnecessary. I think it is a good idea to either warn users from using these options when they choose to not use -volreg_tlrc_warp, or change afni_proc.py, such that it behaves differently when -volreg_tlrc_warp is not chosen.

I hope I have explained the issue clearly but please feel free to let me know if I had any misunderstandings.
Thanks!

Hi, Mingbo-

I will let Rick way in for other/better ideas, but I think that in your code, you would want to adjust more if you don’t want to warp to standard space. Namely, you should remove the “tlrc” block from the list of processing blocks, and all “-tlrc…”-named options (in addition to removing “-volreg_tlrc_warp”, which you have already done). Therefore, your command would read:


afni_proc.py -out_dir $subj.results -subj_id $subj \
#-blocks despike tshift align tlrc volreg mask scale regress \
-blocks despike tshift align   volreg mask scale regress \
-script $subj/proc.$subj.test -scr_overwrite \
-radial_correlate_blocks volreg \
-copy_anat $fs_dir/brain.finalsurfs.nii.gz \
-anat_has_skull no \
-anat_follower anat_w_skull anat $fs_dir/${subj}_SurfVol.nii \
-anat_follower_ROI aaseg anat $fs_dir/aparc.a2009s+aseg.nii.gz \
-anat_follower_ROI aeseg epi $fs_dir/aparc.a2009s+aseg.nii.gz \
-anat_follower_ROI aaseggm anat $fs_dir/aparc.a2009s+aseg_REN_gmrois.nii.gz \
-anat_follower_ROI aeseggm epi $fs_dir/aparc.a2009s+aseg_REN_gmrois.nii.gz \
-anat_follower_ROI FSvent epi $fs_dir/aparc.a2009s+aseg_REN_vent.nii.gz \
-anat_follower_ROI FSwmat epi $fs_dir/aparc.a2009s+aseg_REN_wmat.nii.gz \
-anat_follower_erode FSvent FSwmat \
-dsets $str_dsets \
-tshift_opts_ts -tpattern @$all_out_dir/../slice_timing.txt \
-align_opts_aea -cost lpc+ZZ -giant_move -check_flip \
#-tlrc_base MNI152_2009_template_SSW.nii.gz \
#-tlrc_NL_warp \
-volreg_align_to MIN_OUTLIER \
-volreg_post_vr_allin yes \
-volreg_pvra_base_index MIN_OUTLIER \
-volreg_align_e2a \
-mask_epi_anat yes \
-regress_motion_per_run \
-regress_ROI_PC FSvent 3 \
-regress_ROI_PC FSwmat 3 \
-regress_ROI_PC_per_run FSvent FSwmat \
-regress_make_corr_vols aeseggm FSvent \
-regress_apply_mot_types demean deriv \
-html_review_style pythonic

… where you could remove the lines starting with “#”—I just put them there to demonstrate what I removed.

–pt

Indeed, as Paul notes, though afni_proc.py could likely be reasonably fixed to handle that, it seems just begging for trouble (in terms of both the complexity of afni_proc.py itself, and of people running it correctly). So my inclination for a “fix” would be to simply have the program error out, meaning you could not do it anyway.

Out of curiosity, why are you inclined to run the analysis in orig space, while wanting results in standard space? Unless there is basically zero motion for the subjects, that generally would not be worth doing.

  • rick

Thanks!
The reason of wanting the data to be in orig space is to minimize warping and resampling done to the epi data. And I think the script might have also got some failure when I tried to warp to standard space. But having an alignment with the template will allow warping of atlases into the orig space.

For that, I would still not include the tlrc block. You can get everything aligned to the vr_base EPI, including anat followers.

And then a completely separate step could be to compute a standard space warp via @SSwarper (using anat_w_skull), say, to invert and pull atlases back to orig space with.

Does that seem reasonable?

  • rick

Thanks Rick!
That totally make sense. Just in case other people with similar preference of analyzing in orig space make the same mistake of start modifying command from this recommended example, I suggest adding just a bit of warning in the doc page against my usage or throw out some error message if people use the same combination of options I used. Maybe some explanation about this was already in the doc but I somehow missed it. Sorry if that is the case.

Okay, I added a check for that, thanks!

  • rick