How to apply nonlinear warp parameters to existing preprocessed files?

AFNI version info (afni -ver): Precompiled binary macos_13_ARM: Apr 7 2025 (Version AFNI_25.1.00 'Maximinus')

Dear AFNI experts,

Is there a way to apply nonlinear warp parameters to existing preprocessed files (so that the warp is applied to all output data), without the need to reprocess it all again?

I've used the following preprocessing pipeline for my subjects (example script for one subject):

set subj = '241113LB'
set tdir = '/Volumes/Data/fMRI_ToneLanguage/data/timing_models/241113LB'

cd /Volumes/Data/fMRI_ToneLanguage/data/241113LB

ln -s 241113LB_prosody_run1_20241113162218_3.nii ${subj}_MB_prosody_run1.nii
ln -s 241113LB_prosody_run2_20241113162218_7.nii ${subj}_MB_prosody_run2.nii
ln -s 241113LB_prosody_run3_20241113162218_11.nii ${subj}_MB_prosody_run3.nii
ln -s 241113LB_prosody_run4_20241113162218_15.nii ${subj}_MB_prosody_run4.nii

ln -s 241113LB_MPRAGE-GRAPPA2-1x1x1-208sl-100pcFOV_20241113162218_18.nii ${subj}_MB_anat.nii

ln -s 241113LB_prosody_run4_PE_REV_20241113162218_17.nii ${subj}_MB_prosody_prev4.nii

	afni_proc.py -subj_id ${subj} \
		-script afni_proc_${subj}_prosody_task.tcsh \
		-out_dir afni_proc_${subj}_prosody_task.results \
		-dsets ${subj}_MB_prosody_run1.nii ${subj}_MB_prosody_run2.nii \
			${subj}_MB_prosody_run3.nii ${subj}_MB_prosody_run4.nii \
		-copy_anat ${subj}_MB_anat.nii \
		-anat_has_skull yes \
		-blocks align tlrc volreg mask blur scale regress \
		-blip_reverse_dset ${subj}_MB_prosody_prev4.nii \
		-blip_forward_dset ${subj}_MB_prosody_run4.nii \
		-radial_correlate_blocks tcat volreg regress \
		-tcat_remove_first_trs 6 \
		-align_unifize_epi local \
		-align_opts_aea -cost lpc+ZZ \
						-giant_move \
						-check_flip \
		-tlrc_base MNI152_2009_template.nii.gz \
		-volreg_align_to MIN_OUTLIER \
		-volreg_align_e2a \
		-volreg_tlrc_warp \
		-volreg_warp_dxyz 3 \
		-volreg_compute_tsnr yes \
		-blur_size 4 \
		-blur_in_automask \
		-regress_reml_exec \
		-regress_motion_per_run \
		-regress_local_times \
		-regress_censor_motion 0.3 \
		-regress_stim_times $tdir/241113LB_consistent75_exact.txt \
							$tdir/241113LB_consistent100_exact.txt \
							$tdir/241113LB_conflicting75_exact.txt \
							$tdir/241113LB_conflicting100_exact.txt \
		-regress_stim_labels consistent75 consistent100 conflicting75 conflicting100 \
		-regress_stim_types AM1 \
		-regress_basis 'dmUBLOCK(-1)' \
		-regress_opts_3dD \
			-gltsym 'SYM: +consistent75 + consistent100 -conflicting75 -conflicting100' \
			-glt_label 1 'ConsistentConflicting' \
			-jobs 4 \
		-regress_make_ideal_sum sum_ideal.1D \
		-regress_est_blur_epits \
		-regress_est_blur_errts \
		-regress_run_clustsim no \
		-html_review_style pythonic \
		-execute

As far as I understand, I missed the -tlrc_NL_warp \ option in my preprocessing script. It would be great if I could apply it to the already processed data rather than having to reprocess everything. Could you please help? Thanks!

Howdy-

This is possible. Indeed, we normally recommend people to calculate nonlinear alignment prior to running AP, so that it is faster to run and re-run AP itself. This would typically be done for human data by running sswarper2 to calculate both skullstripping (SS) and nonlinear alignment (warping) of the subject anatomical to a reference template; for nonhuman datasets, the @animal_warper program accomplishes both goals, and its results can be used in exactly the same way.

When telling AP that you want to be using nonlinear alignment in the tlrc block you add this opt:

-tlrc_NL_warp

... otherwise, it will use affine registration only (which might be useful for quick assessments, but not more polished processing).

We would typically also then add this (which I see you already have in your AP command):

-volreg_tlrc_warp

... which does:

With this option, the EPI data will be warped to standard space
in the volreg processing block.  All further processing through
regression will be done in standard space.

The sswarper2 and @animal_warper programs each output the full anatomical->template warp in 2 pieces: an initial affine alignment (*.1D text file) and a nonlinear warp refinement (*.nii.gz dataset with 3 volumes, because we live in a 3D world). That information is provided, along with a version of warped anatomical in standard space, in afni_proc.py with the following kind of template:

-tlrc_NL_warped_dsets                         \
    DSET_ANAT_IN_TEMPLATE                     \
    1D_AFFINE_FILE                            \
    DSET_WARP

If you had run sswarper2 specifically, this would look like:

-tlrc_NL_warped_dsets                         \
    anatQQ.${subj}.nii                        \
    anatQQ.${subj}.aff12.1D                   \
    anatQQ.${subj}_WARP.nii

So, what did you use to calculate your nonlinear alignment, but didn't apply? Did you happen to use sswarper2 (or its precursor, @SSwarper)? Then you can just add that to your existing AP command, along with the above two options.

(If you just used 3dQwarp on its own or auto_warp.py, you can still apply those results here, but those programs include the affine parameters in the warp dataset, rather than leaving the pieces separate; so, instead of a *.1D file to add separately, you could make your own identity-affine-matrix file, which you could call "mat_identity.aff12.1D", made up of these 12 numbers in a row: 1 0 0 0 1 0 0 0 1 0 0 0; you would provide that along with your full warp.)

--pt

ps: here is your AP command from above, with vertical alignment of opts+args, which I find helpful for reading:

afni_proc.py                                                                 \
    -subj_id                  ${subj}                                        \
    -script                   afni_proc_${subj}_prosody_task.tcsh            \
    -out_dir                  afni_proc_${subj}_prosody_task.results         \
    -dsets                    ${subj}_MB_prosody_run1.nii                    \
                              ${subj}_MB_prosody_run2.nii                    \
                              ${subj}_MB_prosody_run3.nii                    \
                              ${subj}_MB_prosody_run4.nii                    \
    -copy_anat                ${subj}_MB_anat.nii                            \
    -anat_has_skull           yes                                            \
    -blocks                   align tlrc volreg mask blur scale regress      \
    -blip_reverse_dset        ${subj}_MB_prosody_prev4.nii                   \
    -blip_forward_dset        ${subj}_MB_prosody_run4.nii                    \
    -radial_correlate_blocks  tcat volreg regress                            \
    -tcat_remove_first_trs    6                                              \
    -align_unifize_epi        local                                          \
    -align_opts_aea           -cost lpc+ZZ                                   \
                              -giant_move                                    \
                              -check_flip                                    \
    -tlrc_base                MNI152_2009_template.nii.gz                    \
    -volreg_align_to          MIN_OUTLIER                                    \
    -volreg_align_e2a                                                        \
    -volreg_tlrc_warp                                                        \
    -volreg_warp_dxyz         3                                              \
    -volreg_compute_tsnr      yes                                            \
    -blur_size                4                                              \
    -blur_in_automask                                                        \
    -regress_reml_exec                                                       \
    -regress_motion_per_run                                                  \
    -regress_local_times                                                     \
    -regress_censor_motion    0.3                                            \
    -regress_stim_times       $tdir/241113LB_consistent75_exact.txt          \
                              $tdir/241113LB_consistent100_exact.txt         \
                              $tdir/241113LB_conflicting75_exact.txt         \
                              $tdir/241113LB_conflicting100_exact.txt        \
    -regress_stim_labels      consistent75 consistent100 conflicting75       \
                              conflicting100                                 \
    -regress_stim_types       AM1                                            \
    -regress_basis            'dmUBLOCK(-1)'                                 \
    -regress_opts_3dD         -gltsym                                        \
                              'SYM: +consistent75 + consistent100 -conflicting75 -conflicting100' \
                              -glt_label 1 'ConsistentConflicting'           \
                              -jobs 4                                        \
    -regress_make_ideal_sum   sum_ideal.1D                                   \
    -regress_est_blur_epits                                                  \
    -regress_est_blur_errts                                                  \
    -regress_run_clustsim     no                                             \
    -html_review_style        pythonic                                       \
    -execute