alignment epi to anat using afni_proc.py

Hi,

I have a afni_proc command to do the alignment from epi to anat:


afni_proc.py -subj_id sub03 -dsets dmeanf_sub03.nii -blocks align volreg -volreg_align_e2a  -copy_anat T1.nii

the resulted proc.sub03 script has the align block codes like this:


# ================================= align ==================================
# for e2a: compute anat alignment transformation to EPI registration base
# (new anat will be intermediate, stripped, T1_ns+orig)
align_epi_anat.py -anat2epi -anat T1+orig \
       -save_skullstrip -suffix _al_junk  \
       -epi vr_base+orig -epi_base 0      \
       -epi_strip 3dAutomask              \
       -volreg off -tshift off

This codes work perfectly for my data. But just out of curiosity, the comments and the parameter (-anat2epi) both showed that it seems like the matrix is from anat to epi? Am i ignoring something very obvious?

Thanks a lot! Have a good weekends!

Mengxing

below is the full codes of proc.sub03

#!/bin/tcsh -xef

echo “auto-generated by afni_proc.py, Sat Jul 20 11:17:59 2019”
echo “(version 6.45, July 19, 2019)”
echo “execution started: date

to execute via tcsh:

tcsh -xef proc.sub03 |& tee output.proc.sub03

to execute via bash:

tcsh -xef proc.sub03 2>&1 | tee output.proc.sub03

=========================== auto block: setup ============================

script setup

take note of the AFNI version

afni -ver

check that the current AFNI version is recent enough

afni_history -check_date 27 Jun 2019
if ( $status ) then
echo “** this script requires newer AFNI binaries (than 27 Jun 2019)”
echo " (consider: @update.afni.binaries -defaults)"
exit
endif

the user may specify a single subject to run with

if ( $#argv > 0 ) then
set subj = $argv[1]
else
set subj = sub03
endif

assign output directory name

set output_dir = $subj.results

verify that the results directory does not yet exist

if ( -d $output_dir ) then
echo output dir “$subj.results” already exists
exit
endif

set list of runs

set runs = (count -digits 2 1 1)

create results and stimuli directories

mkdir $output_dir
mkdir $output_dir/stimuli

copy anatomy to results dir

3dcopy T1.nii $output_dir/T1

============================ auto block: tcat ============================

apply 3dTcat to copy input dsets to results dir,

while removing the first 0 TRs

3dTcat -prefix $output_dir/pb00.$subj.r01.tcat dmeanf_sub03.nii’[0…$]’

and make note of repetitions (TRs) per run

set tr_counts = ( 1 )

-------------------------------------------------------

enter the results directory (can begin processing data)

cd $output_dir

--------------------------------

extract volreg registration base

3dbucket -prefix vr_base pb00.$subj.r01.tcat+orig"[0]"

================================= align ==================================

for e2a: compute anat alignment transformation to EPI registration base

(new anat will be intermediate, stripped, T1_ns+orig)

align_epi_anat.py -anat2epi -anat T1+orig
-save_skullstrip -suffix _al_junk
-epi vr_base+orig -epi_base 0
-epi_strip 3dAutomask
-volreg off -tshift off

================================= volreg =================================

align each dset to base volume, to anat

register and warp

foreach run ( $runs )
# register each volume to the base image
3dvolreg -verbose -zpad 1 -base vr_base+orig
-1Dfile dfile.r$run.1D -prefix rm.epi.volreg.r$run
-cubic
-1Dmatrix_save mat.r$run.vr.aff12.1D
pb00.$subj.r$run.tcat+orig

# create an all-1 dataset to mask the extents of the warp
3dcalc -overwrite -a pb00.$subj.r$run.tcat+orig -expr 1     \
       -prefix rm.epi.all1

# catenate volreg/epi2anat xforms
cat_matvec -ONELINE                                         \
           T1_al_junk_mat.aff12.1D -I                       \
           mat.r$run.vr.aff12.1D > mat.r$run.warp.aff12.1D

# apply catenated xform: volreg/epi2anat
3dAllineate -base T1_ns+orig                                \
            -input pb00.$subj.r$run.tcat+orig               \
            -1Dmatrix_apply mat.r$run.warp.aff12.1D         \
            -mast_dxyz 2                                    \
            -prefix rm.epi.nomask.r$run

# warp the all-1 dataset for extents masking 
3dAllineate -base T1_ns+orig                                \
            -input rm.epi.all1+orig                         \
            -1Dmatrix_apply mat.r$run.warp.aff12.1D         \
            -mast_dxyz 2 -final NN -quiet                   \
            -prefix rm.epi.1.r$run

# make an extents intersection mask of this run
3dTstat -min -prefix rm.epi.min.r$run rm.epi.1.r$run+orig

end

make a single file of registration params

cat dfile.r*.1D > dfile_rall.1D

compute motion magnitude time series: the Euclidean norm

(sqrt(sum squares)) of the motion parameter derivatives

1d_tool.py -infile dfile_rall.1D -set_nruns 1
-derivative -collapse_cols euclidean_norm
-write motion_${subj}_enorm.1D

----------------------------------------

create the extents mask: mask_epi_extents+orig

(this is a mask of voxels that have valid data at every TR)

(only 1 run, so just use 3dcopy to keep naming straight)

3dcopy rm.epi.min.r01+orig mask_epi_extents

and apply the extents mask to the EPI data

(delete any time series with missing data)

foreach run ( $runs )
3dcalc -a rm.epi.nomask.r$run+orig -b mask_epi_extents+orig
-expr ‘a*b’ -prefix pb01.$subj.r$run.volreg
end

warp the volreg base EPI dataset to make a final version

cat_matvec -ONELINE T1_al_junk_mat.aff12.1D -I > mat.basewarp.aff12.1D

3dAllineate -base T1_ns+orig
-input vr_base+orig
-1Dmatrix_apply mat.basewarp.aff12.1D
-mast_dxyz 2
-prefix final_epi_vr_base

create an anat_final dataset, aligned with stats

3dcopy T1_ns+orig anat_final.$subj

record final registration costs

3dAllineate -base final_epi_vr_base+orig -allcostX
-input anat_final.$subj+orig |& tee out.allcostX.txt

-----------------------------------------

warp anat follower datasets (identity: resample)

================== auto block: generate review scripts ===================

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 basic -subj_dir . \
    -uvar_json out.ss_review_uvars.json
tcsh @ss_review_html |& tee out.review_html
apqc_make_html.py -qc_dir QC_$subj

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

endif

return to parent directory (just in case…)

cd …

echo “execution finished: date

==========================================================================

script generated by the command:

afni_proc.py -subj_id sub03 -dsets dmeanf_sub03.nii -blocks align volreg \

-volreg_align_e2a -copy_anat T1.nii

Hi Mengxing,

No, you are correct, but it is okay, and not so obvious why.

In the anat block, the anat is always aligned to the EPI. However, due to that e2a option, the inverse of that (a2e) transformation is applied to the EPI (via the cat_matvec command using -I). That transformation is concatenated with the volreg one to prevent multiple interpolation steps.

Does that seem reasonable?

  • rick

oo yeah that’s right, I missed that -I option. Now that makes sense to me!

Thanks rick!