align one run to another using align_api_anat.py and 3DAllineate - bad results

AFNI version info (afni -ver): Apr 2 2024 (Version AFNI_24.1.00 'Publius Septimius Geta')

Hi Afni people,
I am trying to align one scanning session (with many api runs and one anat) to another session by aligning the 2 anat scans first using align_api_anat.py, and then aligning the epi using the transformation matrix using 3DAllineate.

Something in these transformations is not working, and the first step already produces bad-looking results (that are less aligned than the original images).

Thanks in advance!
Maya

align_epi_anat.py \
			-dset1 $anat_ref_path/anat_final.${subject}.MovieStability.${group}.s3.rest1+orig.BRIK.gz \
			-dset2 $rest_path/anat_final.${subject}.MovieStability.${group}.${session}.rest1+orig.BRIK.gz \
			-dset2to1 \
			-cost lpa


		3dAllineate \
			-cubic \
			-1Dmatrix_apply $data_path/anat_final.${subject}.MovieStability.${group}.${session}.rest1_al_mat.aff12.1D \
			-prefix alignTOs3_$errts_name \
			-input $errts

		3dresample \
			-master $anat_ref_path/errts.${subject}.MovieStability.${group}.s3.rest1.tproject+orig.BRIK.gz \
			-prefix alignTOs3_resampled_$errts_name \
			-input alignTOs3_$errts_name+orig.BRIK.gz

Underlay here is the reference anat_final (session 3), and overlay is anat_final of the scan I want to align (session 1) before any alignment:

Underlay here is the reference anat_final (session 3), and overlay is anat_final of the scan I want to align (session 1) after align_api_anat:

also, in the epi after 3DAllineate there is an addition of a contour line that I don't know where it comes from:
(here the overlay is the epi after 3DAllineate and resample)

This is the proc.py code that I performed to all runs:

afni_proc.py \
     -subj_id $subject.$experiment.$group.$session.$scan \
     -out_dir ${output_path}/$subject.$experiment.$group.$session.$scan.results \
     -script ${output_path}/proc.$subject.$experiment.$group.$session.$scan \
     -blocks despike tshift align volreg mask combine scale regress \
     -radial_correlate_blocks tcat volreg                      \
     -blip_forward_dset $subject.$experiment.$group.$session.AP+orig.HEAD -align_unifize_epi local \
     -blip_reverse_dset $subject.$experiment.$group.$session.PA+orig.HEAD \
     -copy_anat $subject.$experiment.$group.$session.anatMASK+orig.BRIK \
     -anat_has_skull no \
     -dsets_me_run $subject.$experiment.$group.$session.${scan}*0?+orig.HEAD \
     -echo_times 13.2 34.72 56.24 \
     -reg_echo 1                                               \
     -tcat_remove_first_trs 4                                  \
     -tshift_interp -wsinc9                                    \
     -align_opts_aea -cost lpc+ZZ -check_flip            \
     -volreg_align_to MIN_OUTLIER                              \
     -volreg_align_e2a                                         \
     -mask_epi_anat yes                                        \
     -mask_apply anat \
     -combine_method m_tedana                                    \
     -html_review_style pythonic \
     -scr_overwrite

Hi, Maya-

Taking a step back. Here is your afni_proc.py cmd, just spaced vertically:

afni_proc.py                                                                 \
    -subj_id                  $subject.$experiment.$group.$session.$scan     \
    -out_dir                  ${output_path}/$subject.$experiment.$group.$session.$scan.results \
    -script                   ${output_path}/proc.$subject.$experiment.$group.$session.$scan \
    -blocks                   despike tshift align volreg mask combine scale \
                              regress                                        \
    -radial_correlate_blocks  tcat volreg                                    \
    -blip_forward_dset        $subject.$experiment.$group.$session.AP+orig.HEAD \
    -align_unifize_epi        local                                          \
    -blip_reverse_dset        $subject.$experiment.$group.$session.PA+orig.HEAD \
    -copy_anat                $subject.$experiment.$group.$session.anatMASK+orig.BRIK \
    -anat_has_skull           no                                             \
    -dsets_me_run             $subject.$experiment.$group.$session.${scan}*0?+orig.HEAD \
    -echo_times               13.2 34.72 56.24                               \
    -reg_echo                 1                                              \
    -tcat_remove_first_trs    4                                              \
    -tshift_interp            -wsinc9                                        \
    -align_opts_aea           -cost lpc+ZZ                                   \
                              -check_flip                                    \
    -volreg_align_to          MIN_OUTLIER                                    \
    -volreg_align_e2a                                                        \
    -mask_epi_anat            yes                                            \
    -mask_apply               anat                                           \
    -combine_method           m_tedana                                       \
    -html_review_style        pythonic                                       \
    -scr_overwrite

I notice it doesn't include an align block or a tlrc block.

Are you wanting to move the EPIs before processing with afni_proc.py? That will incur extra blurring in them, because they will be regridded separately many times. I might have thought using the second anatomical as the anatomical dataset (via -copy_anat ..) would be the way to go for this?

Re. the alignment here, are any of the involved EPIs or anatomical datasets oblique? (Check using 3dinfo -obliquity ..) That can complicate this.

--pt

Hi Paul,
I want to keep the data in original space, that's why I removed align and tlrc blocks.
I don't think I fully understand what you mean with the second anatomical - should I put the anatomy of session 3 in the processing code of session 1 in -copy_anat line? will this align the epi to the other anatomy?
All raw data here is oblique, but I fix it before the proc.py - the input for copy_anat (*anatMASK) is already plumb, and the errts output is also plumb.

Maya

Hi, Maya-

You do still have an "align" block in your list of blocks in the original AP command. Do you want it there?

Re. obliquity: I expect the output of afni_proc.py to be non-oblique, as a result of processing, indeed.

Having oblique EPIs as input is fine and pretty common. Having oblique anatomicals can be fine, but can also create hassles in some cases (different software deal with obliquity differently; in concatenating transforms it has to be accounted for separately in some cases; it is ignored in some of the visualizations, to avoid blurring/resampling and to allow for direct time series viewing in the GUI still).

As another principle, it will generally be preferable to not regrid the EPIs separately, because that incurs extra blurring on them. Every regridding processing (resampling to a new grid or applying obliquity) leads to interpolation, which inherently blurs. Only things like pure translation, purging obliquity or rescaling voxels are coordinate transforms that do not lead to interpolation+blurring.

Maybe stepping back, you have data (EPI + anatomicals) in session 1 and data in session 2. You want all EPIs in the "space" of session 2; more specifically, is the final space in session 2 that of the subject EPI or that of the subect anatomical?

--pt

Hi Paul,

I think it didn't work when I removed the block completely. Should I try again without it?

I don't think it matters if the final space is the anatomical or the EPI, but I want all EPI's to be aligned. I guess the subject's anatomical from session 3 should be the better space to align to.

Thank you,
Maya