This program performs calculations on 3D warps defined on a grid.
- The fundamental idea is a ‘stack’ of warps, with operators being
applied to the top element(s) of the stack.
- ++ If you don’t know what a computer science ‘stack’ is, see
- ++ Also see 1dmatcalc for a similar implementation of a stack
of matrix operations.
- ++ In the explanations below, the stack will be denoted as
[ A B C ... ]
where A is the top element, B the next element, etc. Operations take place using the top one or two elements.
- The expression is a single string enclosed in quotes ‘ or ”,
with operators separated by spaces. See EXAMPLES below.
++ The expression is the last thing on the command line! ++ For scripting convenience, you can actually break the
expression into multiple strings (after all the ‘-‘ options), and they will be re-assembled into one big string for parsing and processing.
operator at least once. Otherwise, the program computes stuff and then just throws it away. (Fun perhaps, but useless.)
program 3dNwarpApply:
same grid as the dataset being transformed. You can define a warp on a high-resolution anatomical grid and apply it to a low-resolution functional dataset, for example – 3dNwarpApply will figure it out.
the same spatial grid!
from within 3dNwarpCalc, if you don’t need the special capabilities of 3dNwarpApply.
inaccurate near the edges of the 3D grid, since they might require extrapolating the warp to the outside of the grid in places, where there is no information.
(after all the options), and they will be re-assembled into the single expression string the controlling C function needs to work.
you have to put the expression string(s) inside single quote ‘ or double quote ” pairs, or else ugly things will happen. (Not as ugly as having a hippopotamus step on your head, but almost.)
- -interp iii == ‘iii’ is the interpolation mode:
- ++ Modes allowed are a subset of those in 3dAllineate:
- linear quintic wsinc5
++ The default interpolation mode is ‘quintic’. ++ ‘linear’ is much faster but less accurate. ++ ‘wsinc5’ is much slower but more accurate.
- -ainterp jjj == ‘jjj’ is the interpolation mode for the ‘&apply’ operation.
- ++ Modes allowed here are
- NN linear cubic quintic wsinc5
- ++ If this option isn’t given, then the value from ‘-interp’
- is used (which should be good enough for government work).
- -verb == print (to stderr) various fun messages along the road
- ++ A second ‘-verb’ gives you even more fun!
- The program 3dAllineate with the -nwarp_save option will save a
displacement representation of a nonlinear warp to a 3D dataset with 3 sub-bricks (1 for each of x, y, and z).
The contents of these sub-bricks are the displacments of each voxel in mm. ++ The identity warp would be all zero, for example.
- An input warp dataset can contain extra sub-bricks – only the first 3
are used.
If you want the volume distortion at each voxel, use the program 3dNwarpFuncs.
- In the explanations below, the single character ‘x’ represents a 3D
coordinate vector, and a capital letter such as ‘A’ represents a whole 3D warp function, whose output at a particular location is ‘A(x)’.
- You can replace the ‘&’ character that starts a command with ‘%’ or ‘@’,
if that is more convenient for you.
Operator names are not case sensitive: &INVERT is the same as &invert.
&readwarp(FF) (volumes) storing the xyz displacments of each grid point.
of a 3D dataset specified by the filename ‘FF’.
- ++ This operation is to be used to create a starting point
- for calculations that otherwise do not involve a warp defined on a grid, such a polynomial warps.
- ++ The actual data in ‘FF’ is ignored by ‘&identwarp’; only the
- 3D grid definition in the header is actually needed.
specifying a warp as a polynomial, as output from ‘3dAllineate -1Dparam_save’.
12 ==> affine (shifts+angles+scales+shears) 64 ==> cubic (3rd order) polyomial
172 ==> quintic (5th order) polynomial 364 ==> heptic (7th order) polynomial 664 ==> nonic (9th order) polynomial
- file should contain 12 numbers in the order:
- r11 r12 r13 r14 r21 r22 r23 r24 r31 r32 r33 r34
- which will be organized into the 3D transformation matrix:
- r11 r12 r13 r14 r21 r22 r23 r24 r31 r32 r33 r34 0.0 0.0 0.0 1.0
++ One way to get this matrix is via ‘3dAllineate -1Dmatrix_save’. ++ This matrix should have non-zero determinant!
[ A B C ... ] goes to [ B A C ... ] after &swap
the warp J(x) such that A(J(x)) = x.
Jnew(x) = Jold( 2*x - A(Jold(x)) )
which requires 1 warp composition and 1 warp interpolation for each step.
the warp Q(x) such that Q(Q(x)) = A(x).
its square root: the warp R(x) such that A(R(R(x)) = x.
adapted from the Denman-Beavers method for computing the square root of a matrix:
- initialize Y(x) = A(x) and Z(x) = x; then iterate
- Ynew(x) = 0.5*(Yold(x)+inv(Zold(x))) Znew(x) = 0.5*(Zold(x)+inv(Yold(x)))
which converges to Y=sqrt(A) and Z=invsqrt(A).
the warp S(x) = A(A(x)). Equivalent to ‘&dup &compose’.
++ To compute the fourth power of a warp: ‘&sqr &sqr’ ++ To compute the third power of a warp: ‘&dup &sqr &compose’ ++ ‘&square’ is a synonym for this operation.
factor ‘a’ in all 3 dimensions.
++ The case a=-1 is NOT the inverse warp!
then replace BOTH of them with the result.
++ NOTE: you can produce a non-invertible warp this way!
whose name is given by the ‘DD’ argument, to produce a dataset whose prefix is given by the ‘PP’ argument.
++ This operation does not affect the stack of warps. ++ &apply is provided to make your life simpler and happier :-) ++ &apply is like 3dNwarpApply with the output dataset PP
always being on the same grid as the input dataset DD.
** Read a warp from a dataset, invert it, save the inverse.
3dNwarpCalc ‘&readnwarp(Warp+tlrc.HEAD) &invert &write(WarpInv)’
and save that – ideally, the output warp displacements would be identically zero (i.e., the identity warp), and the ‘hexvol’ entries would be constant and equal to the voxel volume.
the result with the original warp – the result should be the identity warp (i.e., all zero displacments) – except for numerical errors, of course.
3dNwarpCalc ‘&readnwarp(Warp+tlrc.HEAD) &dup &invsqrt &sqr &compose &write(WarpOut)’
AUTHOR – RWCox – August 2011
automatic parallelizer software toolkit, which splits the work across multiple CPUs/cores on the same shared memory computer.
by a network (e.g., OpenMP doesn’t work with ‘cluster’ setups).
your system. You can control this value by setting environment variable OMP_NUM_THREADS to some smaller value (including 1).
using all CPUs available. ++ However, on some systems (such as the NIH Biowulf), it seems to be
necessary to set OMP_NUM_THREADS explicitly, or you only get one CPU.
count, since using more than (say) 16 threads is probably useless.
since OpenMP queries this variable BEFORE the program actually starts. ++ You can’t usefully set this variable in your ~/.afnirc file or on the
command line with the ‘-D’ option.
it was coded. You’ll have to experiment on your own systems!
The number of CPUs on this particular computer system is ...... 16.
The maximum number of CPUs that will be used is now set to .... 7.
++ Compile date = Dec 16 2015