Epi 2 anat alignment using afni_proc.py and orbitofrontal cortex

AFNI version info (afni -ver):

afni_24.0

Hi, I'm using afni_proc.py to align an EPI volume to an anat volume using the script below. But despite the fact that I specified 'epi2anat' in '-align_opts_aea' and also '-volreg_align_e2a', the resulting align_epi_anat.py in subid.proc script always ends up being -anat2epi. as seen below.

afni_proc.py \
    -subj_id ag587 \
    -copy_anat T1.nii \
    -anat_has_skull yes \
    -dsets rest.nii.gz \
    -blocks align volreg mask \
    -align_opts_aea -epi2anat -cost lpc+ZZ -giant_move -check_flip  \
    -volreg_align_e2a \
    -volreg_align_to MIN_OUTLIER \
    -mask_epi_anat yes

The align_epi_anat.py command is from subjectid.proc script file.

align_epi_anat.py -anat2epi -anat T1+orig              \
       -save_skullstrip -suffix _al_junk               \
       -epi vr_base_min_outlier+orig -epi_base 0       \
       -epi_strip 3dAutomask                           \
       -cost lpc+ZZ -giant_move -check_flip -volreg on \
       -volreg off -tshift off

The resulting alignment is quite good (see screenshot), but it does not perform resampling of EPI to anat resampling to match anat volume resolution because I'm guessing align_epi_anat.py feeds in the '- anat2epi' option. Would appreciate it if somebody could let me know how I need to revise my afni_proc.py to align my epi2anat.

Another question I have is regarding the orbitofrontal area. You can see that the orbitofrontal area in the screenshot is not red as the rest of the brain, and the raw fMRI is that way, so it's not an alignment problem. It's as if that area is almost not getting any BOLD signals. I wanted to see if other people have experienced this and have any wisdom regarding why this might be happening.

Thank you,

Howdy-

For the first question, the anatomical is actually aligned to the EPI, so any option to specify the anatomical output resolution, not the EPI. I think you could add "-master_anat SOMETHING" to the list of -align_opts_aea .. options, where something is a mm value for the final, isotropic anatomical spatial resolution.

To choose your final EPI dataset resolution at the end of the processing, you would use this option:

-volreg_warp_dxyz VALUE

... where VALUE specifies the final, isotropic EPI data spatial resolution.

But just to check, is it really necessary to regrid the FMRI data to the anatomical? Usually the latter is much higher spatial resolution, and there is little benefit of upsampling but a big cost to it---data disk usage increases, processing time greatly increases and computer RAM/memory requirements jump up.

For a description and set of rationales for more AP processing options, please see:

  • Reynolds RC, Glen DR, Chen G, Saad ZS, Cox RW, Taylor PA (2024). Processing, evaluating and understanding FMRI data with afni_proc.py. Imaging Neuroscience 2:1-52.
    https://doi.org/10.1162/imag_a_00347

For the second question, since you have included the "regress" block, you should have the full APQC HTML output, which has some useful images for EPI-anatomical alignment.

Could you please go into the afni_proc.py's output results directory, and run this command to open the APQC HTML and jump to the ve2a (= volume view of EPI-to-anatomical alignment) QC block :

open_apqc.py -jump_to ve2a -infiles QC_*/index.html

... and copy+paste a copy of that image here?

For a description about more of the APQC HTML, please see:

... as well as this new AFNI Academy YouTube playlist about the APQC HTML, perhaps.

thanks,
pt

Dear Paul,

Thank you so much for your swift reply and the resources!

  1. The reason I thought I had to align epi to anat and have it in anat resolution is because I have a gray matter mask in anat space that I want to use as is (something like in the screenshot below). Warping the gray matter mask hasn't worked out great for me, especially because I work with scans from older adults and their cortical ribbons are very thin. Would there be another way where I can use a conserved gray matter mask without having to warp epi to anat?

  2. If aligning epi to anat is the only way to use the gray matter mask, would there be away to align epi to anat (i.e., the reverse of what I did)?

  3. I couldn't find an APQC HTML file. I do have this block in my proc.subid script, but it didn't seem to have run because I don't have @ss_review_basic in the output directory for some reason. Instead, I have a file named "@epi_review.ag587".



# ========================= auto block: QC_review ==========================
# generate quality control review scripts and HTML report

# generate a review script for the unprocessed EPI data
gen_epi_review.py -script @epi_review.$subj \
    -dsets pb00.$subj.r*.tcat+orig.HEAD

# ========================== auto block: finalize ==========================

# remove temporary files
\rm -f rm.*

# if the basic subject review script is here, run it
# (want this to be the last text output)
if ( -e @ss_review_basic ) then
    ./@ss_review_basic |& tee out.ss_review.$subj.txt

    # generate html ss review pages
    # (akin to static images from running @ss_review_driver)
    apqc_make_tcsh.py -review_style pythonic -subj_dir . \
        -uvar_json out.ss_review_uvars.json
    apqc_make_html.py -qc_dir QC_$subj

    echo "\nconsider running: \n"
    echo "   afni_open -b $subj.results/QC_$subj/index.html"
    echo ""
endif

I would greatly appreciate any advice you may be able to provide on how to move forward.

In short, I am trying to process a resting-state scan with minimal modification to the data, including motion correction, smoothing, grand-mean scaling, and detrending. I previously performed these steps using individual AFNI commands rather than the afni_proc.py wrapper, but based on my initial visual review, the alignment produced by afni_proc.py is substantially better. I would therefore prefer to continue using the wrapper if possible.

Hi-

Re. #1: you can include that anatomical-space dataset as a follower, and it will be regridded to the final EPI space in the end. You can use one of hte following 2 options, depending on whether

  • that dataset is integer-valued and should be interpolated with nearest-neighbor (NN) mode, to preserve integers; in that case, use:
     -anat_follower_ROI LABEL GRID DSET : specify anat follower ROI dataset
    
         e.g. -anat_follower_ROI aaseg anat aparc.a2009s+aseg_REN_all.nii.gz
         e.g. -anat_follower_ROI FSvent epi fs_ap_latvent.nii.gz
    
         Use this option to pass any anatomical follower dataset.  Such a
         dataset is warped by any transformations that take the original
         anat to anat_final.
    
         Similar to -anat_follower, except that these anatomical follower
         datasets are resampled using nearest neighbor (NN) interpolation,
         to preserve data values (as opposed to -anat_follower, which uses
         wsinc5).  That is the only difference between these options.
    
            LABEL    : to name and refer to this dataset
            GRID     : which grid should this be sampled on, anat or epi?
            DSET     : name of input dataset, changed to copy_af_LABEL
    
         Labels defined via this option may be used in -regress_ROI or _PC.
    
  • or it is floating-point valued, and can be interpolated with a cubic or something, in which case use:
        -anat_follower LABEL GRID DSET : specify anat follower dataset
    
             e.g. -anat_follower GM anat FS_GM_MASK.nii
    
         Use this option to pass any anatomical follower dataset.  Such a
         dataset is warped by any transformations that take the original
         anat to anat_final.
    
         Anatomical follower datasets are resampled using wsinc5.  The only
         difference with -anat_follower_ROI is that such ROI datasets are
         resampled using nearest neighbor interpolation.
    
            LABEL    : to name and refer to this dataset
            GRID     : which grid should this be sampled on, anat or epi?
            DSET     : name of input dataset, changed to copy_af_LABEL
    
         A default anatomical follower (in the case of skull stripping) is
         the original anat.  That is to get a warped version that still has
         a skull, for quality control.
    

From your description, it sounds like you have a map of GM, which would likely be integer valued, and so I guess using the first would be appropriate, and getting it to be on the EPI grid at the end could be done with, like:

-anat_follower_ROI seg_gm epi <dset_with_gm_mask>

Re. #2: I think this is made moot by the answer to #1. The EPI-anatomical alignment direction can be flipped, but it is just an intermediate step, and tends to work out better the way it is done in practice, and since the "follower" option gives you what you want for including the GM, then why mess with well-working alignment?

Re. #3: Oh, I see, you haven't included a "regress" block, actually. I misread that initially. Even if you don't care about the regression results, just add it at the end of your list of blocks, so:

    -blocks align volreg mask regress

... in order to have the QC generated (otherwise it won't be).

And actually, since you are doing full resting state processing, you will want the regress block there. I would then also add in these opts for processing (you can choose what censor thresholds you want, these are kind of general starting points, or you can remove them if you want, but that seems risky with resting state):

 -regress_apply_mot_types     demean deriv                        \
-regress_motion_per_run                                          \
-regress_censor_motion       0.2                                 \
-regress_censor_outliers     0.05                                \
-regress_est_blur_epits                                          \
-regress_est_blur_errts                                          \

Some further blocks to consider:

  • And you can scale your data with local voxelwise scaling, so the units have meaningful interpretations as local BOLD % signal change, which we would recommend over grand mean scaling (see here), just by adding a "scale" block to your list of blocks.
  • While adding blocks for resting state, you might want to add a "despike" at the beginning, to remove some likely motion effects.
  • if you have timeshift information, you could add a "tshift" block
  • If you are doing voxelwise analysis, it would be common to blur the data a bit, so you can add a "blur" block and blur value, which for single-echo FMRI we would recommend something like 1.5-2 times your EPI's minimum voxel dimension.

So then your block list (and blur opt) could be:

-blocks      despike tshift align tlrc volreg mask blur scale regress  \
-blur_size   BLUR_SIZE \

Again, much of this depends on your analysis goals.

--pt

This is getting a little hard to track, so let me mostly respond to the original question.
With the original AP command, the EPI will indeed be aligned to the anat at the end. That does not happen in the align block, but in the volreg block (where the anat->epi alignment is inverted).
As Paul noted, the resolution will still default to very near the original EPI resolution, though you can control it with -volreg_warp_dxyz. Also as Paul noted, you can copy the mask as an anatomical follower, though use -anat_follower_ROI to use NN resampling and 'epi' to specify the EPI grid (at whatever dxyz you specify with -volreg_warp_dxyz), e.g.

-anat_follower_ROI  anat_mask epi MY_ANAT_MASK.nii

Does that seem reasonable?
-rick