error while using @animal_warper

afni --version
Precompiled binary macos_13_ARM: Apr 1 2026 (Version AFNI_26.0.11 'Pupienus Maximus')

Hi Afni Experts,

I am currently trying to use @animal_warper to align a dataset to a template, save the warp and inverse warp, apply those transforms to follower datasets like atlases, segmentations, and masks, and do skull stripping by warping a template brain mask back to native space. I looked at both the datasets in ITK snap and both the native and template centers are way apart. So I used itksnap to clisely register them to have the same center as the template space and use animal warper. But everytime i run following code, I get the following error. Could some please shine light on why this is happening. I perfromed this before brining the centers of both the datasets close and wide apart.

#!/usr/bin/env bash
set -euo pipefail

# ============================================================
# Usage:
#   bash step1_aw_manual_followers.sh /path/to/sub-001
# ============================================================

SUBJ_DIR="$1"

IN_DIR="${SUBJ_DIR}/input"
OUT_DIR="${SUBJ_DIR}/proc/step1_aw_manual"
mkdir -p "${OUT_DIR}"

# ------------------------------------------------------------
# USE NATIVE SUBJECT IMAGES HERE, NOT T1toPNI50 / T2toPNI50
# ------------------------------------------------------------
T1="${IN_DIR}/t1.nii.gz"
T2="${IN_DIR}/t2.nii.gz"

TEMPLATE_T1="/Volumes/work/Python_projects/Volumetric_analysis/Project_test/T1_template_PIGI50/PNI50.nii.gz"
TEMPLATE_BRAINMASK="/Volumes/work/Python_projects/Volumetric_analysis/Project_test/T1_template_PIGI50/mask_filled.nii.gz"
TEMPLATE_GM="/Volumes/work/Python_projects/Volumetric_analysis/Project_test/T1_template_PIGI50/gm.nii.gz"
TEMPLATE_WM="/Volumes/work/Python_projects/Volumetric_analysis/Project_test/T1_template_PIGI50/wm.nii.gz"
TEMPLATE_CSF="/Volumes/work/Python_projects/Volumetric_analysis/Project_test/T1_template_PIGI50/csf.nii.gz"

[[ -f "${T1}" ]] || { echo "ERROR: Missing ${T1}"; exit 1; }
[[ -f "${TEMPLATE_T1}" ]] || { echo "ERROR: Missing ${TEMPLATE_T1}"; exit 1; }
[[ -f "${TEMPLATE_BRAINMASK}" ]] || { echo "ERROR: Missing ${TEMPLATE_BRAINMASK}"; exit 1; }
[[ -f "${TEMPLATE_GM}" ]] || { echo "ERROR: Missing ${TEMPLATE_GM}"; exit 1; }
[[ -f "${TEMPLATE_WM}" ]] || { echo "ERROR: Missing ${TEMPLATE_WM}"; exit 1; }
[[ -f "${TEMPLATE_CSF}" ]] || { echo "ERROR: Missing ${TEMPLATE_CSF}"; exit 1; }

echo "=== Step 1 manual AFNI workaround ==="

# ------------------------------------------------------------
# 1. Reorient native images
# ------------------------------------------------------------
3dresample -orient RAI -input "${T1}" -prefix "${OUT_DIR}/T1_RAI.nii.gz"

HAS_T2=0
if [[ -f "${T2}" ]]; then
  3dresample -orient RAI -input "${T2}" -prefix "${OUT_DIR}/T2_RAI.nii.gz"
  HAS_T2=1
fi

cd "${OUT_DIR}"

# ------------------------------------------------------------
# 2. Run @animal_warper WITHOUT follower datasets
#    We only want the registration products here
# ------------------------------------------------------------
@animal_warper                                                     \
    -input        "${OUT_DIR}/T1_RAI.nii.gz"                       \
    -input_abbrev subjT1                                            \
    -base         "${TEMPLATE_T1}"                                  \
    -base_abbrev  PNI50                                             \
    -skullstrip   "${TEMPLATE_BRAINMASK}"                           \
    -outdir       aw_results                                        \
    -ok_to_exist

# ------------------------------------------------------------
# 3. Find the actual qwarp output written by auto_warp
# ------------------------------------------------------------
QWARP=$(find aw_results -path "*awpy_*" -name "anat.*.qw_WARP.nii*" | head -n 1 || true)

if [[ -z "${QWARP}" ]]; then
  echo "ERROR: Could not find qwarp output."
  find aw_results -type f | sort
  exit 1
fi

echo "Found qwarp file:"
echo "  ${QWARP}"

# ------------------------------------------------------------
# 4. Find affine matrix produced by @animal_warper
# ------------------------------------------------------------
AFF_MAT=$(find aw_results/intermediate -name "*_al2std_mat.aff12.1D" | head -n 1 || true)

if [[ -z "${AFF_MAT}" ]]; then
  echo "ERROR: Could not find affine matrix."
  find aw_results/intermediate -type f | sort
  exit 1
fi

echo "Found affine matrix:"
echo "  ${AFF_MAT}"

AFF_INV="aw_results/intermediate/subjT1_inv_al2std_mat.aff12.1D"
cat_matvec -ONELINE "${AFF_MAT}" -I > "${AFF_INV}"

# ------------------------------------------------------------
# 5. Build explicit inverse nonlinear warp from the REAL qwarp
# ------------------------------------------------------------
QWARP_INV="aw_results/intermediate/subjT1_qwarpINV.nii.gz"
3dNwarpCat -prefix "${QWARP_INV}" "INV(${QWARP})"

# ------------------------------------------------------------
# 6. Compose full warps that mirror AFNI's intended logic
#    native -> template
#    template -> native
# ------------------------------------------------------------
OSH2BASE="aw_results/intermediate/subjT1_native2template_WARP.nii.gz"
BASE2OSH="aw_results/intermediate/subjT1_template2native_WARP.nii.gz"

3dNwarpCat \
  -warp1 "${QWARP}" \
  -warp2 "${AFF_MAT}" \
  -prefix "${OSH2BASE}"

3dNwarpCat \
  -warp1 "${AFF_INV}" \
  -warp2 "${QWARP_INV}" \
  -space NO-DSET \
  -prefix "${BASE2OSH}"

# ------------------------------------------------------------
# 7. Apply template masks back into native space
# ------------------------------------------------------------
3dNwarpApply \
  -nwarp "${BASE2OSH}" \
  -source "${TEMPLATE_BRAINMASK}" \
  -master "${OUT_DIR}/T1_RAI.nii.gz" \
  -interp NN \
  -prefix aw_results/brainmask_in_native.nii.gz

3dNwarpApply \
  -nwarp "${BASE2OSH}" \
  -source "${TEMPLATE_GM}" \
  -master "${OUT_DIR}/T1_RAI.nii.gz" \
  -interp NN \
  -prefix aw_results/GM_in_native.nii.gz

3dNwarpApply \
  -nwarp "${BASE2OSH}" \
  -source "${TEMPLATE_WM}" \
  -master "${OUT_DIR}/T1_RAI.nii.gz" \
  -interp NN \
  -prefix aw_results/WM_in_native.nii.gz

3dNwarpApply \
  -nwarp "${BASE2OSH}" \
  -source "${TEMPLATE_CSF}" \
  -master "${OUT_DIR}/T1_RAI.nii.gz" \
  -interp NN \
  -prefix aw_results/CSF_in_native.nii.gz

# ------------------------------------------------------------
# 8. Threshold / binarize
# ------------------------------------------------------------
3dcalc -a aw_results/brainmask_in_native.nii.gz -expr 'step(a-0.5)' -prefix aw_results/brainmask_in_native_bin.nii.gz
3dcalc -a aw_results/GM_in_native.nii.gz       -expr 'step(a-0.5)' -prefix aw_results/GM_in_native_bin.nii.gz
3dcalc -a aw_results/WM_in_native.nii.gz       -expr 'step(a-0.5)' -prefix aw_results/WM_in_native_bin.nii.gz
3dcalc -a aw_results/CSF_in_native.nii.gz      -expr 'step(a-0.5)' -prefix aw_results/CSF_in_native_bin.nii.gz

# ------------------------------------------------------------
# 9. Skull-stripped native T1
# ------------------------------------------------------------
3dcalc \
  -a "${OUT_DIR}/T1_RAI.nii.gz" \
  -b aw_results/brainmask_in_native_bin.nii.gz \
  -expr 'a*step(b)' \
  -prefix aw_results/T1_native_brain.nii.gz

# ------------------------------------------------------------
# 10. Final tissue label map
#    1 = CSF
#    2 = GM
#    3 = WM
# ------------------------------------------------------------
3dcalc \
  -a aw_results/CSF_in_native_bin.nii.gz \
  -b aw_results/GM_in_native_bin.nii.gz \
  -c aw_results/WM_in_native_bin.nii.gz \
  -expr '3*step(c)+2*step((1-step(c))*b)+1*step((1-step(c))*(1-step(b))*a)' \
  -prefix aw_results/tissue_labels_native.nii.gz

echo
echo "=== Done ==="
echo "Check:"
echo "  aw_results/T1_native_brain.nii.gz"
echo "  aw_results/brainmask_in_native_bin.nii.gz"
echo "  aw_results/GM_in_native_bin.nii.gz"
echo "  aw_results/WM_in_native_bin.nii.gz"
echo "  aw_results/CSF_in_native_bin.nii.gz"
echo "  aw_results/tissue_labels_native.nii.gz"
echo "  ${OSH2BASE}"
echo "  ${BASE2OSH}"
echo "  ${QWARP}"

The error is the 3dNwrapCat cannot find the follwing file:
** ERROR: Can't open dataset from file 'anat.un.qw_WARP.nii'

** ERROR: Failed to read 3D warp from 'INV(anat.un.qw_WARP.nii)'

** ERROR: Can't compute nonlinear warp from string 'INV(anat.un.qw_WARP.nii) '

** ERROR: EDIT_dset_items[1]: invalid input dataset

** ERROR: Cannot write dataset: it is invalid

++ DONE! Image output:
       QC/init_qc_02.input_aff+base.subjT1

#++ auto_warp.py version: 0.06
-- clearing AFNI_COMPRESSOR ...
# Output directory /Volumes/work/Python_projects/Volumetric_analysis/Project_test/sub-001/proc/step1_aw_manual/aw_results/awpy_subjT1_pshft/
#Script is running (command trimmed):
  mkdir ./awpy_subjT1_pshft/
cd /Volumes/work/Python_projects/Volumetric_analysis/Project_test/sub-001/proc/step1_aw_manual/aw_results/awpy_subjT1_pshft/
#Script is running (command trimmed):
  3dcopy /Volumes/work/Python_projects/Volumetric_analysis/Project_test/sub-001/proc/step1_aw_manual/aw_results/intermediate/subjT1_shft_aff.nii.gz ./anat.nii
++ 3dcopy: AFNI version=AFNI_26.0.11 (Apr  1 2026) [64-bit]
#Script is running (command trimmed):
  3dUnifize -GM -input ./anat.nii -prefix ./anat.un.nii
++ 3dUnifize: AFNI version=AFNI_26.0.11 (Apr  1 2026) [64-bit]
 + Pre-processing: ADV...............UW[s120448]Gm
++ Output dataset ./anat.un.nii
++ ===== CPU time = 46.5 sec  Elapsed = 9.0
#Script is running (command trimmed):
  3dcopy /Volumes/work/Python_projects/Volumetric_analysis/Project_test/T1_template_PIGI50/PNI50.nii.gz ./base.nii
++ 3dcopy: AFNI version=AFNI_26.0.11 (Apr  1 2026) [64-bit]
#Script is running (command trimmed):
  3dAttribute DELTA ./anat.un.nii
#Script is running (command trimmed):
  3dAttribute DELTA ./base.nii
0.596591 0.596591
#Script is running (command trimmed):
  3dinfo -same_grid ./anat.un.nii ./base.nii
#Script is running (command trimmed):
  3dresample -inset ./anat.un.nii -prefix ./anat.rwb.nii -rmode Li -master ./base.nii
#++ Aligning /Volumes/work/Python_projects/Volumetric_analysis/Project_test/sub-001/proc/step1_aw_manual/aw_results/awpy_subjT1_pshft/base.nii data to /Volumes/work/Python_projects/Volumetric_analysis/Project_test/sub-001/proc/step1_aw_manual/aw_results/awpy_subjT1_pshft/anat.rwb.nii data
#Script is running (command trimmed):
  3dQwarp -prefix ./anat.rwb.qw.nii -blur -3 -3 -workhard:0:2 -maxlev 09 -base ./base.nii -source ./anat.rwb.nii 
OMP: Info #276: omp_set_nested routine deprecated, please use omp_set_max_active_levels instead.
++ OpenMP thread count = 15
++ 3dQwarp: AFNI version=AFNI_26.0.11 (Apr  1 2026) [64-bit]
++ Authored by: Zhark the (Hermite) Cubically Warped
++ negative values in base ==> using strict Pearson correlation
++ Dataset final zero-pad: xbot=44 xtop=44  ybot=36 ytop=36  zbot=20 ztop=20 voxels
++ Weightizing the base image: FWHM = 4.5 (vox)
++ +++++++++++ Begin warp optimization:  base=/Volumes/work/Python_projects/Volumetric_analysis/Project_test/sub-001/proc/step1_aw_manual/aw_results/awpy_subjT1_pshft/base.nii  source=/Volumes/work/Python_projects/Volumetric_analysis/Project_test/sub-001/proc/step1_aw_manual/aw_results/awpy_subjT1_pshft/anat.rwb.nii
++ AFNI warpomatic: 440 x 357 x 190 volume ; autobbox = 41..397 30..323 14..174 [clock= 8s 894ms]
lev=0 1..438 1..355 1..188: [first cost=-0.21020] ..... done [cost:-0.21020==>-0.24715]
lev=1 patch=329x267x141 [clock= 1m 25s 153ms]........:[cost=-0.26590]:........done [cost:-0.24715==>-0.29289 ; 16 patches optimized, 0 skipped, bbox=3:436,3:355,-23:188]
lev=2 patch=247x199x105 [clock= 2m 20s 235ms]...........:[cost=-0.33037]:..........done [cost:-0.29289==>-0.37431 ; 21 patches optimized, 3 skipped, bbox=3:436,3:355,-34:188]
lev=3 patch=185x149x79 [clock= 3m 2s 754ms]............done [cost:-0.37431==>12.47312 ; 32 patches optimized, 4 skipped, bbox=3:436,3:355,-37:188]
lev=4 patch=139x113x59 [clock= 3m 39s 804ms]..............done [cost:12.47312==>17.00923 ; 100 patches optimized, 25 skipped, bbox=3:436,3:355,-35:188]
lev=5 patch=103x85x45 [clock= 4m 27s 791ms]................done [cost:17.00923==>9.88767 ; 202 patches optimized, 50 skipped, bbox=3:436,3:355,-30:188]
lev=6 patch=77x63x33 [clock= 5m 19s 796ms]..........................done [cost:9.88767==>9.13047 ; 599 patches optimized, 211 skipped, bbox=3:436,3:355,-26:188]
lev=7 patch=59x47x25 [clock= 6m 29s 410ms].........................................done [cost:9.13047==>5.88609 ; 1335 patches optimized, 537 skipped, bbox=3:436,3:355,-20:188]
lev=8 patch=43x35x19 [clock= 8m 2s 323ms].........................................................done [cost:5.88609==>5.05206 ; 3317 patches optimized, 1596 skipped, bbox=3:436,3:355,-18:188]
lev=9 patch=33x27x15 [clock= 10m 30s 318ms]..............................................................................................done [cost:5.05206==>4.93081 ; 7178 patches optimized, 3470 skipped, bbox=3:436,3:355,-16:188]
++ ====== total number of parameters 'optimized' = 153750
 +      initial unpenalized cost = -0.210196
 +        final unpenalized cost = -0.41405
 +        final penalized   cost = 4.93081
++ Output dataset ./anat.rwb.qw.nii
++ Output dataset ./anat.rwb.qw_WARP.nii
++ ===== CPU time = 4266.7 sec  clock time = 14m 48s 783ms
#++ Applying warps to /Volumes/work/Python_projects/Volumetric_analysis/Project_test/sub-001/proc/step1_aw_manual/aw_results/intermediate/subjT1_shft_aff.nii.gz
#Script is running (command trimmed):
  3dNwarpApply -nwarp ./anat.rwb.qw_WARP.nii -master ./base.nii -source /Volumes/work/Python_projects/Volumetric_analysis/Project_test/sub-001/proc/step1_aw_manual/aw_results/intermediate/subjT1_shft_aff.nii.gz -prefix ./subjT1_shft_aff.aw.nii 
++ 3dNwarpApply: AFNI version=AFNI_26.0.11 (Apr  1 2026) [64-bit]
++ Authored by: Zhark the Warped
++ -master dataset is './base.nii'
++ opened source dataset '/Volumes/work/Python_projects/Volumetric_analysis/Project_test/sub-001/proc/step1_aw_manual/aw_results/intermediate/subjT1_shft_aff.nii.gz'
++ Processing -nwarp 
++ Warping:.Z
++ Output dataset ./subjT1_shft_aff.aw.nii
++ total CPU time = 33.9 sec  Elapsed = 2.7
#++ Saving history
#Script is running (command trimmed):
  3dNotes -h "auto_warp.py -overwrite -base \
 /Volumes/work/Python_projects/Volumetric_analysis/Project_test/T1_template_PIGI50/PNI50.nii.gz \
 -affine_input_xmat ID -qworkhard 0 2 -input \
 intermediate/subjT1_shft_aff.nii.gz -output_dir awpy_subjT1_pshft \
 -qw_opts -maxlev 09" \
 ./subjT1_shft_aff.aw.nii


++ 3dNwarpCat: AFNI version=AFNI_26.0.11 (Apr  1 2026) [64-bit]
++ Authored by: Zhark the Warper
** ERROR: Can't open dataset from file 'anat.un.qw_WARP.nii'
** ERROR: Failed to read 3D warp from 'INV(anat.un.qw_WARP.nii)'
** ERROR: Can't compute nonlinear warp from string 'INV(anat.un.qw_WARP.nii) '
** ERROR: EDIT_dset_items[1]: invalid input dataset
** ERROR: Cannot write dataset: it is invalid

Fatal Signal 11 (SIGSEGV) received
  3dNwarpCat
 Bottom of Debug Stack
** AFNI version = AFNI_26.0.11  Compile date = Apr  1 2026
** [[Precompiled binary macos_13_ARM: Apr  1 2026]]
** Program Death **
** If you report this crash to the AFNI message board,
** please copy the error messages EXACTLY, and give
** the command line you used to run the program, and
** any other information needed to repeat the problem.
** You may later be asked to upload data to help debug.
** Crash log is appended to file /Users/myru/.afni.crashlog
++ 3drefit: AFNI version=AFNI_26.0.11 (Apr  1 2026) [64-bit]
++ Authored by: RW Cox
** ERROR: Can't open dataset anat.un.qw_WARPINV.nii
++ 3drefit processed 0 datasets
++ 3dcopy: AFNI version=AFNI_26.0.11 (Apr  1 2026) [64-bit]
3dcopy: No match.
** ERROR: program failed (autowarp cp)```

The program ended and I am not sure what the case of failure is. 

![init_qc_02.input_aff+base.subjT1|690x130](upload://oCRjxWm8lppzuzY3hAZtJYBfZ7P.jpeg)

Thank you for your help in advance. 
Pavan.

Howdy-

Hmm, that is odd. Your command looks fine. I just ran a similar one on my computer (from the MACAQUE_DEMO dataset) and it ran through.

To see what outputs were created by AW, what is the output of this command:

find ./aw_results -name "*.nii*" | sort

?

Also, on a side note, it looks like you are warping extra datasets outside of the @animal_warper command, separately. That can be done, sure, but you should be able to do that within AW itself. You can use various "follower" options to send integer-valued and floating-point valued data from either native->template space or vice versa. Please check out the help file for these:

  -atlas_followers ATL1 ATL2 ATL3 ...
  -seg_followers S1 S2 S3 ...
  -template_followers T1 T2 T3 ...
  -dset_followers D1 D2 D3 ...
  -roidset_followers dset1 dset2 ...

--pt

Thank you Taylor. I am trying AFNI animal_warper for the first time so gives me some confidance that my path is correct. I will definitely try the followers in my next step once i have the following working. Based on the output files, below are the .nii ourput files form aw.

./sub-001/proc/step1_aw_manual/aw_results/awpy_subjT1_pshft/anat.nii
./sub-001/proc/step1_aw_manual/aw_results/awpy_subjT1_pshft/anat.rwb.nii
./sub-001/proc/step1_aw_manual/aw_results/awpy_subjT1_pshft/anat.rwb.qw_WARP.nii
./sub-001/proc/step1_aw_manual/aw_results/awpy_subjT1_pshft/anat.rwb.qw.nii
./sub-001/proc/step1_aw_manual/aw_results/awpy_subjT1_pshft/anat.un.nii
./sub-001/proc/step1_aw_manual/aw_results/awpy_subjT1_pshft/base.nii
./sub-001/proc/step1_aw_manual/aw_results/awpy_subjT1_pshft/subjT1_shft_aff.aw.nii
./sub-001/proc/step1_aw_manual/aw_results/intermediate/subjT1_pshft_al2std.nii.gz
./sub-001/proc/step1_aw_manual/aw_results/intermediate/subjT1_pshft.nii.gz
./sub-001/proc/step1_aw_manual/aw_results/intermediate/subjT1_shft_aff.nii.gz
./sub-001/proc/step1_aw_manual/aw_results/intermediate/subjT1_shft.nii.gz
./sub-001/proc/step1_aw_manual/aw_results/mask_filled.nii.gz
./sub-001/proc/step1_aw_manual/aw_results/PNI50.nii.gz
./sub-001/proc/step1_aw_manual/aw_results/subjT1_shft_WARP.nii.gz
./sub-001/proc/step1_aw_manual/aw_results/subjT1.nii.gz

Pavan.

Hi, Pavan-

Thanks, that is helpful to see.

The very odd thing is that these files:

./sub-001/proc/step1_aw_manual/aw_results/awpy_subjT1_pshft/anat.rwb.nii
./sub-001/proc/step1_aw_manual/aw_results/awpy_subjT1_pshft/anat.rwb.qw_WARP.nii
./sub-001/proc/step1_aw_manual/aw_results/awpy_subjT1_pshft/anat.rwb.qw.nii

have unexpected names, and I am not sure why they are named that. I don't see those in the output of my program. I have files named:

./sub-001/proc/step1_aw_manual/aw_results/awpy_subjT1_pshft/anat.un.nii
./sub-001/proc/step1_aw_manual/aw_results/awpy_subjT1_pshft/anat.un.qw_WARP.nii
./sub-001/proc/step1_aw_manual/aw_results/awpy_subjT1_pshft/anat.un.qw.nii

Can you please copy+paste the output of running:

3dinfo ./sub-001/proc/step1_aw_manual/aw_results/awpy_subjT1_pshft/anat.rwb.nii

and

3dinfo ./sub-001/proc/step1_aw_manual/aw_results/awpy_subjT1_pshft/anat.rwb.qw.nii

... so I can see the history of them?

thanks,
pt

Hi again, Pavan-

I have continued to look at this further, including running your processing script but changing names/paths for working on the MACAQUE_DEMO dataset. There are a few useful things I found.

First, the @animal_warper (AW) command ran fine for me, and completed successfully. So, that is good, except that I remain uncertain as to why you got the error messages you reported.

Second, your script stopped for me after this line

QWARP=$(find aw_results -path "*awpy_*" -name "anat.*.qw_WARP.nii*" | head -n 1 || true)

in this check, with an error message: ERROR: Could not find qwarp output. This is because the subdirectory created by auto_warp.py, called awpy_*, will not be saved by default when running AW. You would have to add the -keep_temp option for that to happen.

Third, even when I add -keep_temp in the AW command, I do not gett any anat.rwb*nii files. How those appear in your output still remain mysterious to me. I have files with similar names, except with un where you have rwb.

Fourth, I still don't think you need to search for intermediate warps to apply to map data from template space to original space or vice versa. That is what using the -follower_* options that I noted in my previous reply will do. Please give those a try, and let us know if there are any issues. That will save you a lot of unnecessary work and scripting. It will also manage the interpolations appropriately.

Fifth, on a minor scripting note, for the purposes of using AW at least, you don't need to resample the input to have RAI orientation. In all of the AFNI alignment programs, dataset orientation does not matter, because the programs use the xyz-based locations for alignment. You can align datasets of any orientation to any datasets of any orientation.

So, at this point, I am unable to replicate the errors you saw. Please let me know if any of the above points help provide a way around those errors.

But maybe one additional thing to check would be the initial overlap of the anatomical and template datasets. As noted in the AFNI Academy Alignment tutorials, having reasonable overlap to start with helps avoid issues. I know you mentioned doing some manual recentering in a different software; it would still be helpful to verify visually that that went well. In the QC subdirectory of the AW output, there are lots of images of initial, intermediate (and eventually final) datasets. Could you perhaps share what the init_qc_*.jpg images look like? That will give a sense of initial alignment (before any processing has started), as well as through intermediate points like after center-of-mass alignment, affine alignment, and some nonlinear alignment.

thanks,
pt

Hi Taylor,

Below are the outputs of the requested info for both the datasets.

For the output shown below, I first registered the data using ITK snap to bring the anatomy close to the template space and then performed @animal_warper.

i will try the -keep_temp command to see if that make helps.

3dinfo ./sub-001/proc/step1_aw_manual/aw_results/awpy_subjT1_pshft/anat.rwb.nii

++ 3dinfo: AFNI version=AFNI_26.0.11 (Apr  1 2026) [64-bit]

Dataset File:    /Volumes/work/Python_projects/Volumetric_analysis/Project_test/sub-001/proc/step1_aw 9.55.24 AM/aw_results/awpy_subjT1_pshft/anat.rwb.nii
Identifier Code: AFN_AJ8hIjcx77fgkzJK_IHjNQ  Creation Date: Thu Apr  2 08:56:19 2026
Template Space:  ORIG
Dataset Type:    Anat Bucket (-abuc)
Byte Order:      LSB_FIRST {assumed} [this CPU native = LSB_FIRST]
Storage Mode:    NIFTI
Storage Space:   60,192,000 (60 million) bytes
Geometry String: "MATRIX(0.596591,0,0,-103.0894,0,0,0.8,-80.2643,0,0.596591,0,-31.1575):352,285,150"
Data Axes Tilt:  Plumb
Data Axes Orientation:
  first  (x) = Right-to-Left
  second (y) = Inferior-to-Superior
  third  (z) = Anterior-to-Posterior   [-orient RIA]
R-to-L extent:  -103.089 [R] -to-   106.314 [L] -step-     0.597 mm [352 voxels]
A-to-P extent:   -80.264 [A] -to-    38.936 [P] -step-     0.800 mm [150 voxels]
I-to-S extent:   -31.157 [I] -to-   138.274 [S] -step-     0.597 mm [285 voxels]
Number of values stored at each pixel = 1
  -- At sub-brick #0 '?' datum type is float:            0 to       1390.67

3dinfo ./sub-001/proc/step1_aw_manual/aw_results/awpy_subjT1_pshft/anat.rwb.qw.nii

++ 3dinfo: AFNI version=AFNI_26.0.11 (Apr  1 2026) [64-bit]

Dataset File:    /Volumes/work/Python_projects/Volumetric_analysis/Project_test/sub-001/proc/step1_aw 9.55.24 AM/aw_results/awpy_subjT1_pshft/anat.rwb.qw.nii
Identifier Code: AFN_OTaxe3LlsOqDMAlhhjxLUg  Creation Date: Thu Apr  2 09:11:22 2026
Template Space:  ORIG
Dataset Type:    Anat Bucket (-abuc)
Byte Order:      LSB_FIRST {assumed} [this CPU native = LSB_FIRST]
Storage Mode:    NIFTI
Storage Space:   60,192,000 (60 million) bytes
Geometry String: "MATRIX(0.596591,0,0,-103.0894,0,0,0.8,-80.2643,0,0.596591,0,-31.1575):352,285,150"
Data Axes Tilt:  Plumb
Data Axes Orientation:
  first  (x) = Right-to-Left
  second (y) = Inferior-to-Superior
  third  (z) = Anterior-to-Posterior   [-orient RIA]
R-to-L extent:  -103.089 [R] -to-   106.314 [L] -step-     0.597 mm [352 voxels]
A-to-P extent:   -80.264 [A] -to-    38.936 [P] -step-     0.800 mm [150 voxels]
I-to-S extent:   -31.157 [I] -to-   138.274 [S] -step-     0.597 mm [285 voxels]
Number of values stored at each pixel = 1
  -- At sub-brick #0 '?' datum type is float:            0 to       1390.67

After digging a bit more in to the @animal_warper function, I noticed an internal filename mismatch inside the installed @animal_warper script.

The script internally expected:

anat.un.qw_WARP.nii
anat.un.qw_WARPINV.nii

but in this run the actual nonlinear warp produced by 3dQwarp was:

anat.rwb.qw_WARP.nii

Because of that mismatch, the subsequent 3dNwarpCat inversion/composition step failed when trying to access a file that had never been generated.
Looks like the script mixed two basenames:

  • expected: anat.un...
  • actual: anat.rwb... This appears to happen in the branch where auto_warp.py/@animal_warperresamples the unifized anatomy to the base grid before running3dQwarp`.

This showed the hard-coded inversion block in

set aspace = `3dinfo -space anat.un.qw_WARP.nii`
3dNwarpCat                                                  \
   -warp1  'INV(anat.un.qw_WARP.nii)'                       \
   -prefix  anat.un.qw_WARPINV.nii
3drefit -space ${aspace} anat.un.qw_WARPINV.nii

So I temporarily fixed it by

  1. detect whichever qwarp output actually exists
  • anat.rwb.qw_WARP.nii
  • anat.rwb.qw_WARP.nii.gz
  • anat.un.qw_WARP.nii
  • anat.un.qw_WARP.nii.gz
  1. build the inverse warp from the real qwarp file
  2. copy both warp and inverse warp to the canonical downstream names expected later in the script
  • ${srcsh2_prefix}_WARP.nii.gz
  • ${srcsh2_prefix}_WARPINV.nii.gz

This preserved compatibility with the later 3dNwarpCat steps that already rely on ${srcsh2_prefix} naming.

if ( -e anat.rwb.qw_WARP.nii ) then
    set qwarp_dset = anat.rwb.qw_WARP.nii
else if ( -e anat.rwb.qw_WARP.nii.gz ) then
    set qwarp_dset = anat.rwb.qw_WARP.nii.gz
else if ( -e anat.un.qw_WARP.nii ) then
    set qwarp_dset = anat.un.qw_WARP.nii
else if ( -e anat.un.qw_WARP.nii.gz ) then
    set qwarp_dset = anat.un.qw_WARP.nii.gz
else
    echo "** ERROR: could not find qwarp output dataset"
    \ls -1 anat*.nii*
    exit 1
endif

set qwarp_inv_dset = ""
if ( "${qwarp_dset}" =~ *.nii.gz ) then
    set qwarp_inv_dset = `echo "${qwarp_dset}" | sed 's/_WARP\.nii\.gz$/_WARPINV.nii.gz/'`
else
    set qwarp_inv_dset = `echo "${qwarp_dset}" | sed 's/_WARP\.nii$/_WARPINV.nii/'`
endif

set aspace = `3dinfo -space ${qwarp_dset}`

3dNwarpCat                                                  \
  -warp1  "INV(${qwarp_dset})"                              \
  -prefix ${qwarp_inv_dset}

3drefit -space ${aspace} ${qwarp_inv_dset}

\rm -f ../${srcsh2_prefix}_WARP.nii.gz
\rm -f ../${srcsh2_prefix}_WARPINV.nii.gz

3dcopy ${qwarp_dset}     ../${srcsh2_prefix}_WARP.nii.gz
3dcopy ${qwarp_inv_dset} ../${srcsh2_prefix}_WARPINV.nii.gz
cd -

That fixed the issue, but the registraiton was perfect. So I am looking into what other steps I can adapt to improve my registration.



Thank you.
Pavan.

Hi, Pavan-

Thanks for sharing the 3dinfo output of the anat.rwb.nii and anat.rwb.qw.nii files. Oddly, there is no history section there. That means that those files were not made by an AFNI program, likely.

When you mention "branch", do you mean a branch of the AFNI GitHub repository, or a "branching point" within the @animal_warper script?

I am not seeing how anat.rwb.qw_WARP.nii can exist as a filename. That remains mysterious to me.

Additionally, the 3dinfo output for the expected anat.un.qw.nii file does contain history information:

[ptaylor@Valta-X3: Mon Apr  6 08:57:12 2026] {AFNI_26.0.08:linux_ubuntu_16_64_glw_local_shared} 3dcopy /data/PROJECTS/macaque/MACAQUE_DEMO/NMT_v2.1_sym/NMT_v2.1_sym_05mm/NMT_v2.1_sym_05mm_SS.nii.gz ./base.nii
[ptaylor@Valta-X3: Mon Apr  6 09:00:05 2026] {AFNI_26.0.08:linux_ubuntu_16_64_glw_local_shared} 3dQwarp -prefix ./anat.un.qw.nii -blur -3 -3 -workhard:0:2 -maxlev 09 -base ./base.nii -source ./anat.un.nii

So, if the anat*rwb*.nii files were really the same thing as this these files, they should also have that property. It is additionally mysterious that they don't, and that makes me further surprised. When I ran your script or my earlier command, I captured the log text form the terminal, and there was no "rwb" appearing in either case. Every time the string "qw_WARP" appeared, it was always and only ever preceded by "un.", and never "rwb." or any other string.

I would still like to get to the bottom of what is happening here, and how these differences in filenames exist.

One thing help is if you could copy+paste the output of the AFNI system check:

afni_system_check.py -check_all

Also, would you be able to save a log of all terminal text when you run your script? This depends on what kind of shell you are using; if you run echo $0 then you will see (ignore any - part of the output; that just means it is a login shell).

  • if you are using a bash or zsh, you can save a log with this syntax:
    COMMAND 2>&1 | tee log_script.txt
    
  • if you are using a csh or tcsh, you can save a log with this syntax:
    COMMAND |& tee log_script.txt
    

In your case, the COMMAND is running your bash script, with one argument, like bash SCRIPT.bash SUBJ_ID.

I will send you a message through the message board about sending me the log_script.txt.

Sorry for the hassle of this, but I have never seen this issue or set of differences arise.


In terms of the alignment itself, the slice labels and image types don't appear to be what I would expect. I downloaded the PNI50 templates from here, and they have a few unfortunate properties:

Firstly, there is a lot of non-brain material in the FOV, and there is a very, very wide FOV with a lot of empty space, so the computational times and datasets sizes are probably unnecessarily large.

Second the orientations don't match standard definitions of axial, sagittal and coronal. The above montages show the slice plains in that order---the sagittal is facing upwards, rather than leftwards, for example.

Thirdly, the qform_code and sform_code values are not what they should be for a reference template---namely 5---but instead are 1 and 0, respectively. You can read more about this here.

Fourthly, and most troublingly, these template space datasets have obliquity in them. You can see this with:

3dinfo -obliquity -prefix PNI*

That is really bad and annoying. No template space should have that, and it will cause woe esp. when moving across software, which typically treat obliquity differently.

Fifthly, it is a bit odd that the voxel dimensions are neither isotropic nor perfectly round numbers:

$ 3dinfo -ad3 -prefix PNI50*
0.596591	0.596591	0.800000	PNI50_brain.nii.gz
0.596591	0.596591	0.800000	      PNI50.nii.gz

That is not the biggest deal, but worth being aware of.

I can change/fix some of these. But it will be a question of knowing a bit more about your goals for the data, in terms of how much these changes will matter.

I might email you further about some of this.

--pt