3dNwarpCat with volume registration

Hi AFNI members,

I wanted to concatenate my matrices from the volume registration, epi2anat (I have anat2epi that I inverse), and anat2tlrc (I have MNI to anat that I inverse).

When I was using linear registration for the anat to tlrc, I had this line:

cat_matvec -ONELINE [mni2anat] -I [anat2epi] -I volreg_matrix.aff12.1D > whole_matrix_volreg_epi2anat_tlrc.aff12.1D

Now I am trying to do the same with non-linear registration:

3dNwarpCat -prefix whole_matrix_volreg_epi2anat_WARP -warp3 “INV([mni2anat])” -warp2 “INV([anat2epi])” -warp1 volreg_matrix.aff12.1D

But I have this error:

*+ WARNING: Multi-line matrix file ‘volreg_matrix.aff12.1D’ input when only one matrix is allowed!

I don’t find how I should be doing this. Does 3dNwarpCat allow volreg (3D+time) affine matrices?

P.S. Note that option -nwarp in 3dNwarpApply can work with multi-line matrices. But this is not efficient if I want to apply it on more than one dataset, it has to recompute the matrix concatenation everytime, and I can’t save the final matrix!

Thank you very much,


At this time, 3dNwarpCat cannot save the results from multiple line matrix concatenations with a nonlinear warp – because the result would be multiple nonlinear warps, and I don’t have a file format for that (and the multiple warp file could be gigantic in size).

Only 3dNwarpApply can do the multiple line matrix concatenations, and it does these “on the fly”, so only one catenated nonlinear warp is in memory at a time.

I might be able to modify 3dNwarpApply to allow multiple input and multiple output files, but I’m sure I’m not going to modify 3dNwarpCat for this purpose – it would be somewhat ugly to have to support a file format for multiple nonlinear transformations in all the places where such a thing might appear.

In the meantime, you can shorten the application of the same warp set multiple times (once for each dataset) with 3dNwarpApply by pre-inverting and catenating your -warp2 and -warp3 inputs.

Also, it’s nice to hear from people using the nonlinear warping in AFNI – I haven’t got much feedback on this feature, and since I spent a lot of effort on it, I’m always glad to hear from users.

Thank you very much for your answer, I will indeed invert my other matrices first.

I just started preparing my script for the nonlinear registration, I look forward to seeing the results!

Hi again Bob and other AFNI experts,

to continue with this story, I applied 3dNwarpApply as discusted on a first set of data, everything went well. Now I have a new one, and the script keeps getting “killed”. My guess is that it is because there is not enough RAM. The same issue was presented here[/url] but my data are not so far apart so I don’t think that’s the problem. I also saw [url=https://afni.nimh.nih.gov/pub/dist/doc/misc/OpenMP.html]here that I could use OpenMP but for now it seems a little complicated for me.

Some information:

  • I am running on a virtual machine. My host has 16Gb of RAM, and I tried to give as much as 12.5Gb to the linux guest, but it is still not enough. The “top” function shows me that the %MEM goes up to 96.8% before the kill.
  • The function is:
    anat_warp= the WARP file created by 3dQWarp, from anat+orig to anat+tlrc.
    epi_warp= the affine created by align_epi_anat -anat2epi.
    cat_matvec -ONELINE $epi_warp -I volreg_matrix.aff12.1D > whole_matrix_volreg_epi2anat.aff12.1D
    3dNwarpApply -nwarp “$anat_warp whole_matrix_volreg_epi2anat.aff12.1D”
    -source pb02.$subj.r01.tshift+orig -dxyz 3.5 -prefix rm.epi.nomask -master ~/abin/MNI152_T1_2009c+tlrc

I also checked for differences between this set of data and the previous one, when it worked:
-anat+orig: same size (256x256x256), both float.
-anat+tlrc: same size (MNI size), both float.
-anat_warp from 3dQwarp: This matrix size always varies but it is significantly bigger for the second set of data (~ 230x250x230 for the first, ~530x550x530 for the second).
-results from align_epi_anat: well aligned in both cases.
-epi data is a little bigger in the second set (80x80x34, 150 TR vs 64x64x40, 100 TR)

Do you have ideas that could help reduce the RAM needed? Crop some data with Autobox? Run a different function for every TR in pb02?

Thank you so much,


The problem comes from the fact the that output dataset is created in memory and only written to disk at the end. So if the output dataset gets HUGE, then you run out of memory (which is usually what “killed” means).

To get around this, you could do (as you suggest) a separate 3dNwarpApply for each TR. However, that would be slow, with a lot of file I/O.

You could do a bunch of TRs at a time, say 50. For example (in tcsh syntax)

set nvals = `3dnvals pb02.$subj.r01.tshift+orig`
@ nvm1 = $nvals - 1
set jbot = 0 ; set jstep = 50
while( $jbot < $nvals )
  set ppp = `count -dig 6 $jbot $jbot`
  @ jtop = $jbot + $jstep - 1
  if( $jtop > $nvm1 ) set jtop = $nvm1
  3dNwarpApply \
     -nwarp "$anat_warp  whole_matrix_volreg_epi2anat.aff12.1D{$jbot..$jtop}" \
     -source pb02.$subj.r01.tshift+orig"[$jbot..$jtop]" \
     -dxyz 3.5 -prefix rm.epi.nomask.$ppp -master ~/abin/MNI152_T1_2009c+tlrc
  @ jbot = $jtop + 1
3dTcat -prefix rm.epi.nomask "rm.epi.nomask.0*.HEAD"

In the above (which is not guaranteed to work, since I haven’t tested it), I’m using row selectors “{a…b}” on the matrix file to select a subset of rows to read in, and the corresponding volume (sub-brick) selectors on the input dataset “[a…b]” to select a subset of 3D volumes to process. At the end, all the partial results are 3dTcat-ed together.

I hope the above helps (and works).

Hi Bob,

I tried as you said (with my own program since I am working in bash). Even with as few as 5 TR, it still gets killed.
I also tried with autobox first to try to reduce the size of the EPI. Result was ++ Auto bbox: x=16…60 y=5…65 z=0…33

Result of the 3dNwarpApply was

++ 3dNwarpApply: AFNI version=AFNI_16.3.08 (Nov 4 2016) [64-bit]
++ Authored by: Zhark the Warped
++ opened source dataset ‘pb02.HC_S750.r01.tshift+orig[0…5]’
++ output grid size = 3.5 mm
++ -master dataset is ‘/home/user/abin/MNI152_T1_2009c+tlrc.’
++ Processing -nwarp ++ Enter IW3D_read_nwarp_catlist( …/…/group.anat/HC_S750.results/anat.HC_S750.nsFS2_WARP+tlrc whole_matrix_volreg_epi2anat.aff12.1D{0…5} )

  • Open dataset warp …/…/group.anat/HC_S750.results/anat.HC_S750.nsFS2_WARP+tlrc
  • max displacments = 200.448 66.7855 129.967
  • Open matrix file whole_matrix_volreg_epi2anat.aff12.1D{0…5}
  • max shifts = 3.84855 0.260578 11.6008
  • — Totalized max displacments = 204.297 67.0461 141.568
    ++ IW3D_set_geometry_nwarp_catlist: padding = 204
  • results: master_geomstring = MATRIX(-1,0,0,258,0,-1,0,294,0,0,1,-258):517,554,527 actual_geomstring = MATRIX(-1,0,0,462,0,-1,0,498,0,0,1,-462):925,962,935
  • – warp #0 geometry = MATRIX(-1,0,0,258,0,-1,0,294,0,0,1,-258):517,554,527
  • regridding warp #0 to geometry = MATRIX(-1,0,0,462,0,-1,0,498,0,0,1,-462):925,962,935
    /media/sf_shared_folder/TOOLS-bash//fMRI_preprocessing_newBlur_noDeoblique.sh: line 433: 15804 Killed 3dNwarpApply -verb -nwarp “$anat_warp whole_matrix_volreg_epi2anat.aff12.1D{$start…$end}” -source pb02.$subj.r01.tshift+orig[$start…$end] -dxyz 3.5 -prefix rm.epi.nomask_$i -master ~/abin/MNI152_T1_2009c+tlrc.

The number before the word “Killed” is never the same. But it is always while “regridding warp”

Maybe the problem is not the epi. Do you have any idea why the anat_warp is no much bigger, even if the size of the anat is the same as before?

The matrix transformation indicates there is a large translation. My recommendation is to separately align the centers of the datasets. Applying nonlinear warps over datasets that are very far apart can eat up vast amounts of memory, particularly on high resolution grids.

Super, thank you!

I ran @Align_Centers on both anat and epi (to pre-align them on MNI) and I re-ran everything and this time it worked much faster.

Once again, this forum saves my life!