Yeah, it’s confusing, because there are (at least) two levels of backwards involved.
NB: my own learning on the topic came from and has been memorialized in this pretty long thread discussing this kind of topic:
From the cat_matvec helpfile:
=== COMPUTATIONS ===
If [ U] [v] are the matrix/vector for the first mfile, and
[A] [b] are the matrix/vector for the second mfile, then
the catenated transformation is
matrix = [A][ U] vector = [A][v] + [b]
That is, the second mfile transformation follows the first.
** Thus, the order of matrix multiplication is exactly the **
** opposite of the order of the inputs on the command line! **
So, firstly, algebra notation with left-multiplication means that in “[A][ U] dset”, first the matrix [ U] is applied to the dset, and then matrix [A].
The second level of backwards (I think) is what it means to apply a matrix: normally we thing of “sending” data from one space to another, so the order would be like jumping from source to base: space A → space B and space B → to space C. So, then, reading like the above, we’d want:
cat_matvec map_AtoB mapBtoC > map_AtoC
which should theoretically do: [mapBtoC][map_AtoB] dset.
However, the way the mapping works is to start with the grid of the base/master dset and pull data. Therefore, conceptually we’d want to start in space C, and first pull from space B, and then pull from space A.
It might appear backwards from how we think about it, but it’s because instead of starting from source and moving to base, mapping starts in the base space and pulling data from the source (that way, the final grid is made, and one just decides where to pull data from to populate it). So, start in C and the first operation is to pull from B, then be in B and use the second operation to pull from A. So, the order from the AFNI Bootcamp demo looks like:
cat_matvec -ONELINE \
FT_anat_ns+tlrc::WARP_DATA -I \ # 1) into TLRC from anat
FT_anat_al_junk_mat.aff12.1D -I \ # 2) into anat from one EPI
mat.r$run.vr.aff12.1D > mat.r$run.warp.aff12.1D # 3) within EPI
So, hopefully from a “base originating” rather than a “source originating” point of view (-> insert reference to the “all your base are belong to us” here, if that helps), then it makes more sense how to mesh the helpfile with the implementation.