Using 3dvolreg and 3drotate to Align Intra-Subject Inter-Session Datasets
=========================================================================
When you study the same subject on different days, to compare the datasets
gathered in different sessions, it is first necessary to align the volume
images.  This note discusses the practical difficulties posed by this
problem, and the AFNI solution.

The difficulties include:
 (A) Subject's head will be positioned differently in the scanner -- both
     in location and orientation.
 (B) Low resolution echo-planar images are harder to re-align accurately
     that high resolution SPGR images, when the subject's head is rotated.
 (C) Anatomical coverage of the slices will be different, meaning that
     exact overlap of the data from two sessions may not be possible.
 (D) The anatomical relationship between the EPI and SPGR (MP-RAGE, etc.)
     images may be different on different days.
 (E) The coordinates in the scanner used for the two scanning sessions
     may be different (e.g., slice coverage from 40I to 50S on one day,
     and from 30I to 60S on another).

(B-D) imply that simply using 3dvolreg to align the EPI data from session 2
with EPI data from session 1 won't work well.  3dvolreg's calculations are
based on matching voxel data, but if the images don't cover the same
part of the brain fully, they won't register well.

The AFNI solution is to register the SPGR images from session 2 to session 1,
to use this transformation to move the EPI data from session 2 in the same
way.  The use of the SPGR images as the "parents" gets around difficulty (B),
and is consistent with the extant AFNI processing philosophy.  The SPGR
alignment procedure specifically ignores the data at the edges of the bricks,
so that small (5%) mismatches in anatomical coverage shouldn't be important.
(This also helps eliminate problems with various artifacts that occur at the
edges of images.)

Problem (C) is addressed by zero-padding the EPI datasets in the slice-
direction.  In this way, if the EPI data from session 2 covers a somewhat
different patch of brain than from session 1, the bricks can still be made
to overlap, as long as the zero-padding is large enough to accomodate the
required data shifts.  Zero-padding can be done in one of 3 ways:
 (1) At dataset assembly time, in to3d (using the -zpad option); or
 (2) At any later time, using the program 3dZeropad; or
 (3) By 3drotate (using -gridparent with a previously zero-padded dataset).

Suppose that you have the following 4 datasets:
  S1 = SPGR from session 1    E1 = EPI from session 1
  S2 = SPGR from session 2    E2 = EPI from session 2

Then the following commands will create datasets registered from session 2
into alignment with session 1:

  3dvolreg -twopass -twodup -heptic -clipit -base S1+orig \
           -prefix S2reg S2+orig

  3drotate -heptic -clipit -rotparent S2reg+orig -gridparent E1+orig \
           -prefix E2reg E2+orig

You may want to create the datasets E1 and E2 using the -zpad option to
to3d, so that they have some buffer space on either side to allow for
mismatches in anatomical coverage in the slice direction.  Note that
the use of the "-gridparent" option to 3drotate implies that the output
dataset E2reg will be sampled to the same grid as dataset E1.  If needed,
E2reg will be zeropadded in the slice-direction to make it have the same
size as E1.

If you want to zeropad a dataset after creation, this can be done using
a command line like:

  3dZeropad -prefix E1pad -z 2 E1+orig

which will add 2 slices of zeros to each slice-direction face of each
sub-brick of dataset E1, and write the results to dataset E1pad.

*****************************************************************************

Registration Information Stored in Output Dataset Header by 3dvolreg
=====================================================================
The following attributes are stored in the header of the new dataset:

VOLREG_ROTCOM_NUM    = number of sub-bricks registered
 (1 int)               [may differ from number of sub-bricks in dataset]
                       [if "3dTcat -glueto" is used later to add images]

VOLREG_ROTCOM_xxxxxx = the string that would be input to 3drotate to
 (string)              describe the operation, as in
                   -rotate 1.000I 2.000R 3.000A -ashift 0.100S 0.200L 0.300P
                       [xxxxxx = printf("%06d",n); n=0 to ROTCOM_NUM-1]

VOLREG_MATVEC_xxxxxx = the 3x3 matrix and 3 vector of the transformation
 (12 floats)           generated by the above 3drotate parameters; if
                       U is the matrix and v the vector, then they are
                       stored in the order
                           u11 u12 u13 v1
                           u21 u22 u23 v2
                           u31 u32 u33 v3
                       If extracted from the header and stored in a file
                       in just this way (3 rows of 4 numbers), then that
                       file can be used as input to "3drotate -matvec_dicom"
                       to specify the rotation/translation.

VOLREG_CENTER_OLD    = Dicom order coordinates of the center of the input
 (3 floats)            dataset (about which the rotation takes place).

VOLREG_CENTER_BASE   = Dicom order coordinates of the center of the base
 (3 floats)            dataset.

VOLREG_BASE_IDCODE   = Dataset idcode for base dataset.
 (string)

VOLREG_BASE_NAME     = Dataset .HEAD filename for base dataset.
 (string)

These attributes can be extracted in a shell script using the program
3dAttribute, as in the csh example:

  set rcom = `3dAttribute VOLREG_ROTCOM_000000 Xreg+orig`
  3drotate $rcom -heptic -clipit -prefix Yreg Y+orig

which would apply the same rotation/translation to dataset Y+orig as was
used to produce sub-brick #0 of dataset Xreg+orig.

To see all these attributes, one could execute

  3dAttribute -all Xreg+orig | grep VOLREG

*****************************************************************************
Robert W Cox - 07 Feb 2001
National Institutes of Mental Health
rwcox@codon.nih.gov
