#589352 clarify in documentation/--help the order of transformations

Package:
ants
Source:
ants
Description:
advanced normalization tools for brain and image analysis
Submitter:
Yaroslav Halchenko
Date:
2010-07-18 16:06:08 UTC
Severity:
wishlist
#589352#5
Date:
2010-07-16 21:28:04 UTC
From:
To:
P.S. CCing all possibly interested parties ;)

According to docstring of WarpTimeSeriesImageMultiTransform sequence of
necessary transformations could be arbitrarily long.  Having applied a sequence

MNI -> inverse warp -> inverse affine -> inverse affine

produces different (and looks like incorrect) result from if I do transformations in two steps, e.g.

MNI -> inverse warp -> inverse affine

and then result of previous given for the final inverse affine.

Here is output of running reproduce.sh.  All data, script and
results are available from

http://www.onerussian.com/Linux/bugs/ants.2steps/

I investigate the result by comparing mni2bold.nii.gz  and mni2bold-2.nii.gz
overlayed on top of epi_template.nii.gz. mni2bold.nii.gz seems to be offset
toward anterior

$> ./reproduce.sh
I: Lets do directly all the steps at once
 Running: WarpTimeSeriesImageMultiTransform 4 mni.nii.gz mni2bold.nii.gz -R epi_template.nii.gz anat2mni_InverseWarp.nii.gz  -i anat2mni_Affine.txt -i raiders_func2anat_Affine.txt --use-NN
FIELD: anat2mni_InverseWarp.nii.gz
AFFINE-INV: anat2mni_Affine.txt
AFFINE-INV: raiders_func2anat_Affine.txt
moving_image_filename: mni.nii.gz
output_image_filename: mni2bold.nii.gz
reference_image_filename: epi_template.nii.gz
[0/3]: FIELD: anat2mni_InverseWarp.nii.gz
[1/3]: AFFINE-INV: anat2mni_Affine.txt
[2/3]: AFFINE-INV: raiders_func2anat_Affine.txt
 Four-D image size: [182, 218, 182, 1]
 4D-In-Spc [1, 1, 1, 1]
 4D-In-Org [-90, 126, -72, 0]
 4D-In-Size [182, 218, 182, 1]
 4D-In-Dir 1 0 0 0
0 -1 0 0
0 0 1 0
0 0 0 1

 ......
 4D-Out-Spc [3, 3, 3, 1]
 4D-Out-Org [-70.5, -75.759, 93.1085, 0]
 4D-Out-Size [64, 64, 48, 1]
 4D-Out-Dir -0 0 1 0
1 -0 0 0
0 -1 -0 0
0 0 0 1

 Use Nearest Neighbor interpolation
0 % done ... -0 0 1
1 -0 0
0 -1 -0

 100 % complete
I: Lets do directly all the steps at once
 Step 1 mni->anat: WarpTimeSeriesImageMultiTransform 4 mni.nii.gz mni2anat.nii.gz -R brain_avg.nii.gz anat2mni_InverseWarp.nii.gz  -i anat2mni_Affine.txt --use-NN
FIELD: anat2mni_InverseWarp.nii.gz
AFFINE-INV: anat2mni_Affine.txt
moving_image_filename: mni.nii.gz
output_image_filename: mni2anat.nii.gz
reference_image_filename: brain_avg.nii.gz
[0/2]: FIELD: anat2mni_InverseWarp.nii.gz
[1/2]: AFFINE-INV: anat2mni_Affine.txt
 Four-D image size: [182, 218, 182, 1]
 4D-In-Spc [1, 1, 1, 1]
 4D-In-Org [-90, 126, -72, 0]
 4D-In-Size [182, 218, 182, 1]
 4D-In-Dir 1 0 0 0
0 -1 0 0
0 0 1 0
0 0 0 1

 ......
 4D-Out-Spc [1, 1, 1, 1]
 4D-Out-Org [-86.8253, -128, 132.723, 0]
 4D-Out-Size [256, 256, 176, 1]
 4D-Out-Dir -0 0 1 0
1 -0 0 0
0 -1 -0 0
0 0 0 1

 Use Nearest Neighbor interpolation
0 % done ... -0 0 1
1 -0 0
0 -1 -0

 100 % complete
 Step 2 anat->mni: WarpTimeSeriesImageMultiTransform 4 mni2anat.nii.gz mni2bold-2.nii.gz -R epi_template.nii.gz -i raiders_func2anat_Affine.txt --use-NN
AFFINE-INV: raiders_func2anat_Affine.txt
moving_image_filename: mni2anat.nii.gz
output_image_filename: mni2bold-2.nii.gz
reference_image_filename: epi_template.nii.gz
[0/1]: AFFINE-INV: raiders_func2anat_Affine.txt
 Four-D image size: [256, 256, 176, 1]
 4D-In-Spc [1, 1, 1, 1]
 4D-In-Org [-86.8253, -128, 132.723, 0]
 4D-In-Size [256, 256, 176, 1]
 4D-In-Dir -0 0 1 0
1 -0 0 0
0 -1 -0 0
0 0 0 1

 ......
 4D-Out-Spc [3, 3, 3, 1]
 4D-Out-Org [-70.5, -75.759, 93.1085, 0]
 4D-Out-Size [64, 64, 48, 1]
 4D-Out-Dir -0 0 1 0
1 -0 0 0
0 -1 -0 0
0 0 0 1

#589352#10
Date:
2010-07-16 21:55:37 UTC
From:
To:
yarik --

the order looks wrong to me ... would usually be either

Warp Affine

#589352#15
Date:
2010-07-17 00:38:22 UTC
From:
To:
If two images have different image headers, they are supposed to align
in the physical space, not in the image voxel space, for warping in
ANTS.

I noticed you used two different images as references. Could you try
both use "-R epi_template.nii.gz" and verify if this issue still exists?

Also, are these image real 4D image or just 3D? If they are 3D, you
can try use WarpImageMultiTransform instead with the same syntax.

#589352#20
Date:
2010-07-17 00:38:22 UTC
From:
To:
If two images have different image headers, they are supposed to align
in the physical space, not in the image voxel space, for warping in
ANTS.

I noticed you used two different images as references. Could you try
both use "-R epi_template.nii.gz" and verify if this issue still exists?

Also, are these image real 4D image or just 3D? If they are 3D, you
can try use WarpImageMultiTransform instead with the same syntax.

#589352#25
Date:
2010-07-18 00:08:00 UTC
From:
To:
Yarik.  I think this is user error.    I think that some of the
transformations are out of order.  But it is hard to see unless we have the
original ants commands.

B.


On Jul 16, 2010 5:33 PM, "Yaroslav Halchenko" <debian@onerussian.com> wrote:

Package: ants
Version: 1.9+svn532-3
Severity: normal

P.S. CCing all possibly interested parties ;)

According to docstring of WarpTimeSeriesImageMultiTransform sequence of
necessary transformations could be arbitrarily long.  Having applied a
sequence

MNI -> inverse warp -> inverse affine -> inverse affine

produces different (and looks like incorrect) result from if I do
transformations in two steps, e.g.

MNI -> inverse warp -> inverse affine

and then result of previous given for the final inverse affine.

Here is output of running reproduce.sh.  All data, script and
results are available from

http://www.onerussian.com/Linux/bugs/ants.2steps/

I investigate the result by comparing mni2bold.nii.gz  and mni2bold-2.nii.gz
overlayed on top of epi_template.nii.gz. mni2bold.nii.gz seems to be offset
toward anterior

$> ./reproduce.sh
I: Lets do directly all the steps at once
 Running: WarpTimeSeriesImageMultiTransform 4 mni.nii.gz mni2bold.nii.gz -R
epi_template.nii.gz anat2mni_InverseWarp.nii.gz  -i anat2mni_Affine.txt -i
raiders_func2anat_Affine.txt --use-NN
FIELD: anat2mni_InverseWarp.nii.gz
AFFINE-INV: anat2mni_Affine.txt
AFFINE-INV: raiders_func2anat_Affine.txt
moving_image_filename: mni.nii.gz
output_image_filename: mni2bold.nii.gz
reference_image_filename: epi_template.nii.gz
[0/3]: FIELD: anat2mni_InverseWarp.nii.gz
[1/3]: AFFINE-INV: anat2mni_Affine.txt
[2/3]: AFFINE-INV: raiders_func2anat_Affine.txt
 Four-D image size: [182, 218, 182, 1]
 4D-In-Spc [1, 1, 1, 1]
 4D-In-Org [-90, 126, -72, 0]
 4D-In-Size [182, 218, 182, 1]
 4D-In-Dir 1 0 0 0
0 -1 0 0
0 0 1 0
0 0 0 1

 ......
 4D-Out-Spc [3, 3, 3, 1]
 4D-Out-Org [-70.5, -75.759, 93.1085, 0]
 4D-Out-Size [64, 64, 48, 1]
 4D-Out-Dir -0 0 1 0
1 -0 0 0
0 -1 -0 0
0 0 0 1

 Use Nearest Neighbor interpolation
0 % done ... -0 0 1
1 -0 0
0 -1 -0

 100 % complete
I: Lets do directly all the steps at once
 Step 1 mni->anat: WarpTimeSeriesImageMultiTransform 4 mni.nii.gz
mni2anat.nii.gz -R brain_avg.nii.gz anat2mni_InverseWarp.nii.gz  -i
anat2mni_Affine.txt --use-NN
FIELD: anat2mni_InverseWarp.nii.gz
AFFINE-INV: anat2mni_Affine.txt
moving_image_filename: mni.nii.gz
output_image_filename: mni2anat.nii.gz
reference_image_filename: brain_avg.nii.gz
[0/2]: FIELD: anat2mni_InverseWarp.nii.gz
[1/2]: AFFINE-INV: anat2mni_Affine.txt
 Four-D image size: [182, 218, 182, 1]
 4D-In-Spc [1, 1, 1, 1]
 4D-In-Org [-90, 126, -72, 0]
 4D-In-Size [182, 218, 182, 1]
 4D-In-Dir 1 0 0 0
0 -1 0 0
0 0 1 0
0 0 0 1

 ......
 4D-Out-Spc [1, 1, 1, 1]
 4D-Out-Org [-86.8253, -128, 132.723, 0]
 4D-Out-Size [256, 256, 176, 1]
 4D-Out-Dir -0 0 1 0
1 -0 0 0
0 -1 -0 0
0 0 0 1

 Use Nearest Neighbor interpolation
0 % done ... -0 0 1
1 -0 0
0 -1 -0

 100 % complete
 Step 2 anat->mni: WarpTimeSeriesImageMultiTransform 4 mni2anat.nii.gz
mni2bold-2.nii.gz -R epi_template.nii.gz -i raiders_func2anat_Affine.txt
--use-NN
AFFINE-INV: raiders_func2anat_Affine.txt
moving_image_filename: mni2anat.nii.gz
output_image_filename: mni2bold-2.nii.gz
reference_image_filename: epi_template.nii.gz
[0/1]: AFFINE-INV: raiders_func2anat_Affine.txt
 Four-D image size: [256, 256, 176, 1]
 4D-In-Spc [1, 1, 1, 1]
 4D-In-Org [-86.8253, -128, 132.723, 0]
 4D-In-Size [256, 256, 176, 1]
 4D-In-Dir -0 0 1 0
1 -0 0 0
0 -1 -0 0
0 0 0 1

 ......
 4D-Out-Spc [3, 3, 3, 1]
 4D-Out-Org [-70.5, -75.759, 93.1085, 0]
 4D-Out-Size [64, 64, 48, 1]
 4D-Out-Dir -0 0 1 0
1 -0 0 0
0 -1 -0 0
0 0 0 1

#589352#30
Date:
2010-07-18 00:37:37 UTC
From:
To:
I am yet to double check... kids around...

all data and commands (printed also in the output I've provided) are under
http://www.onerussian.com/Linux/bugs/ants.2steps/

#589352#35
Date:
2010-07-18 02:08:51 UTC
From:
To:
Hi Gang,
good. that is what we thought/assumed... and that (alignment in physical
space) means that having intermediate matrix of voxels to project to
should not have an effect (besides possible quantization/dequantization
into/from voxels), that is why we were surprised with the results
tested... script called reproduce2.sh from the same
http://www.onerussian.com/Linux/bugs/ants.2steps/
produced result mni2bold-2-epi.nii.gz  looks the same as previous
"incorrect" mni2bold-2.nii.gz, so issue does still exist.

if you run reproduce.sh, do you experience the same issue with your
version of ants?
I indeed could... script  reproduce3.sh at the same location -- the same
effect!

#589352#40
Date:
2010-07-18 02:08:51 UTC
From:
To:
Hi Gang,
good. that is what we thought/assumed... and that (alignment in physical
space) means that having intermediate matrix of voxels to project to
should not have an effect (besides possible quantization/dequantization
into/from voxels), that is why we were surprised with the results
tested... script called reproduce2.sh from the same
http://www.onerussian.com/Linux/bugs/ants.2steps/
produced result mni2bold-2-epi.nii.gz  looks the same as previous
"incorrect" mni2bold-2.nii.gz, so issue does still exist.

if you run reproduce.sh, do you experience the same issue with your
version of ants?
I indeed could... script  reproduce3.sh at the same location -- the same
effect!

#589352#45
Date:
2010-07-18 02:21:22 UTC
From:
To:
man, this is a good one... indeed I've used incorrect order for mni2anat
part -- we thought that first affine is taken as the approximation and
then warp for non-linearity (and inverse order in 'reverse')... weird
that it didn't matter much (seems to me, but didnd't check
numerically).

Problem is though persists -- see script reproduce-order.sh, run it and
compare
mni2bold-2-order.nii.gz mni2bold-order.nii.gz

please feel free to use those datafiles and scripts I've provided at
http://www.onerussian.com/Linux/bugs/ants.2steps/
to ease the troubleshooting

#589352#50
Date:
2010-07-18 03:10:16 UTC
From:
To:
After a quick test, I found a small problem of the second
WarpMultiTransform in reproduce3.sh. Here is the output:


  Step 1 mni->anat:
/home/songgang/local/ANTS/gccrel_itk320/WarpImageMultiTransform 3
mni.nii.gz mni2anat-multi.nii.gz -R brain_avg.nii.gz
anat2mni_InverseWarp.nii.gz  -i anat2mni_Affine.txt --use-NN

FIELD: anat2mni_InverseWarp.nii.gz
AFFINE-INV: anat2mni_Affine.txt
moving_image_filename: mni.nii.gz
output_image_filename: mni2anat-multi.nii.gz
reference_image_filename: brain_avg.nii.gz
[0/2]: FIELD: anat2mni_InverseWarp.nii.gz
[1/2]: AFFINE-INV: anat2mni_Affine.txt
User nearest neighbor interpolation (was Haha)
   We check the syntax of your call ....
  Your 1st parameter should be a Warp (not Inverse) when your 2nd
parameter is an affine map --- exiting without applying warp.

Basically it did NOT perform the warping. We did this on purpose as a
sanity check. Typically the transform sequence like
"XXXInverseWarp.nii.gz -i XXXAffine.txt" is not a legit one; the more
reasonable one would be "-i XXXAffine.txt XXXInverseWarp.nii.gz"
instead.

Could you try to switch the inverse warp and the inverse affine here?
If you are sure that you want to put the inverse of affine at last, we
probably would add some option like a "-force" to bypass the sanity
check.

#589352#55
Date:
2010-07-18 03:10:16 UTC
From:
To:
After a quick test, I found a small problem of the second
WarpMultiTransform in reproduce3.sh. Here is the output:


  Step 1 mni->anat:
/home/songgang/local/ANTS/gccrel_itk320/WarpImageMultiTransform 3
mni.nii.gz mni2anat-multi.nii.gz -R brain_avg.nii.gz
anat2mni_InverseWarp.nii.gz  -i anat2mni_Affine.txt --use-NN

FIELD: anat2mni_InverseWarp.nii.gz
AFFINE-INV: anat2mni_Affine.txt
moving_image_filename: mni.nii.gz
output_image_filename: mni2anat-multi.nii.gz
reference_image_filename: brain_avg.nii.gz
[0/2]: FIELD: anat2mni_InverseWarp.nii.gz
[1/2]: AFFINE-INV: anat2mni_Affine.txt
User nearest neighbor interpolation (was Haha)
   We check the syntax of your call ....
  Your 1st parameter should be a Warp (not Inverse) when your 2nd
parameter is an affine map --- exiting without applying warp.

Basically it did NOT perform the warping. We did this on purpose as a
sanity check. Typically the transform sequence like
"XXXInverseWarp.nii.gz -i XXXAffine.txt" is not a legit one; the more
reasonable one would be "-i XXXAffine.txt XXXInverseWarp.nii.gz"
instead.

Could you try to switch the inverse warp and the inverse affine here?
If you are sure that you want to put the inverse of affine at last, we
probably would add some option like a "-force" to bypass the sanity
check.

#589352#60
Date:
2010-07-18 06:01:56 UTC
From:
To:
do you mean like in reproduce-order.sh which I gave for Brian?
http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=589352#45

and it seems it didn't just exit but actually stored result (or am I
wrong? officially I am sleeping now ;))

#589352#65
Date:
2010-07-18 06:01:56 UTC
From:
To:
do you mean like in reproduce-order.sh which I gave for Brian?
http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=589352#45

and it seems it didn't just exit but actually stored result (or am I
wrong? officially I am sleeping now ;))

#589352#70
Date:
2010-07-18 13:56:50 UTC
From:
To:
i believe this is the key to unlock your transforms:

trans_mni2anat="  -i anat2mni_Affine.txt anat2mni_InverseWarp.nii.gz  "
trans_anat2func="-i raiders_func2anat_Affine.txt"
trans_mni2func=" $trans_anat2func $trans_mni2anat "

switch both aff/inv  and the  trans  order ....

#589352#75
Date:
2010-07-18 13:56:50 UTC
From:
To:
i believe this is the key to unlock your transforms:

trans_mni2anat="  -i anat2mni_Affine.txt anat2mni_InverseWarp.nii.gz  "
trans_anat2func="-i raiders_func2anat_Affine.txt"
trans_mni2func=" $trans_anat2func $trans_mni2anat "

switch both aff/inv  and the  trans  order ....

#589352#80
Date:
2010-07-18 16:05:21 UTC
From:
To:
retitle 589352 clarify in documentation/--help the order of transformations
severity 589352 wishlist
thanks

ah... I guess you mean that the order of transformations in command line
is not the order of application but more inline with matrix
representation for linear transformations when new transformation is
obtained by prepending matrix product with yet another matrix...

and indeed reversing the order on this example make results consistent!
script reproduce-order2.sh, just in case...

Cool!  I will check on the rest of the data ;)

So, it is kinda RTFM issue ;)  But, whenever ants.pdf somewhat describes it
(e.g. Figure 7) in this reverted application order, although even more
confusing to me since I would expect BA not AB...  but --help is actually
what confused us I think:

 you can also string together series of mappings --- e.g.:
MyAffine.txt MySecondAffine.txt  MyWarp.nii.gz MySecondWarp.nii.gz -i
MyInverseAffine.txt    --- this can be an arbitrarily long series.

so, it suggests that series of transformations goes T1, T2, not T2, T1

Altogether it seems to be somewhat confusing documentation...? or
it is just me?
N.B. thus retitling and lowering severity of this report.

Thanks!