Skip to content

Part 5: Anatomical Preprocessing

Neal W Morton edited this page Jan 31, 2022 · 2 revisions

Creating an Average MPRAGE image

If you have multiple high-resolution MPRAGE T1 scans, they will need to be registered and averaged to create a single anatomical space for the participant. FreeSurfer will handle registration and averaging; however, it will not deal with nonlinear distortion that may be different for the different MPRAGE scans. This nonlinear distortion is a result of nonlinearities in the gradients used by the scanner to localize signal.

Distortion itself isn't such a problem; if all of a participant's scans were distorted in the same way, this wouldn't cause much issue with most analyses. However, the distortion changes if the position of the participant's head in the bore changes, so there may be differences in distortion of scans taken on different days or even at different times during a session if head position has changed (e.g. if a participant's head has sunk into the padding more).

As a result, it is often a good idea to use nonlinear registration, especially if a participant's MPRAGE scans were taken on different scanning sessions. The merge_anat.sh script will correct for intensity differences across an image (sometimes referred to as bias field), run nonlinear registration using ANTS, scale the images to make them comparable in intensity, and average them.

There are two images in any registration; a moving image and a fixed image. The fixed image stays put, while the moving image is transformed and interpolated to match the fixed image. What MPRAGE scan to use as the fixed image depends on your study. If you collected T2 coronal or FLAIR images also, it's probably best to use the MPRAGE collected on the same day as those.

For the sample tutorial data, we'll use the day 2 MPRAGE scan as the fixed (or reference) image. For one subject, the command will be like:

merge_anat.sh $STUDYDIR/bender_03/anatomy/highres1.nii.gz $STUDYDIR/bender_03/anatomy/highres2.nii.gz $STUDYDIR/bender_03/anatomy/highres.nii.gz

Here, there are three inputs indicating moving image, fixed image, and output image. The output is named just highres.nii.gz (no number) by convention. Note that you can make this command shorter by using relative paths:

cd $STUDYDIR/bender_03/anatomy
merge_anat.sh highres1.nii.gz highres2.nii.gz highres.nii.gz

However, in the tutorial we'll generally use absolute paths (like the ones above starting with $STUDYDIR) because it lets us run the same thing regardless of what the current directory is.

Nonlinear registration takes some time, so we'll submit a job to run our two subjects in parallel, with each merge command having access to 12 cores. It should take about 20 minutes to run; we'll allow a little longer, 30 minutes, for the max job time. Here, we use slaunch, which is like rlaunch but a little simpler because it just loops over subjects instead of both subjects and runs.

Every "{}" is replaced by the subject ID, so in this case every {} is replaced by bender_03 for the first command, and bender_04 for the second command. The two subjects will be run in parallel on one node. It's a lot of code, so let's first run it with the -t flag (it must be placed before the command) to test it out:

slaunch -t "merge_anat.sh $STUDYDIR/{}/anatomy/highres1.nii.gz $STUDYDIR/{}/anatomy/highres2.nii.gz $STUDYDIR/{}/anatomy/highres.nii.gz" bender_03:bender_04

This displays the two commands that will be run, on separate lines:

merge_anat.sh /work/03206/mortonne/lonestar/preproc/bender_03/anatomy/highres1.nii.gz /work/03206/mortonne/lonestar/preproc/bender_03/anatomy/highres2.nii.gz /work/03206/mortonne/lonestar/preproc/bender_03/anatomy/highres.nii.gz
merge_anat.sh /work/03206/mortonne/lonestar/preproc/bender_04/anatomy/highres1.nii.gz /work/03206/mortonne/lonestar/preproc/bender_04/anatomy/highres2.nii.gz /work/03206/mortonne/lonestar/preproc/bender_04/anatomy/highres.nii.gz

If the commands look right, run again without the -t flag and with launch options at the end, to actually submit the job to the cluster to run those commands:

slaunch "merge_anat.sh $STUDYDIR/{}/anatomy/highres1.nii.gz $STUDYDIR/{}/anatomy/highres2.nii.gz $STUDYDIR/{}/anatomy/highres.nii.gz" bender_03:bender_04 -N 1 -n 2 -a 12 -p development -r 00:30:00

Look at the highres image in fslview, and compare to the highres2 image. Note the bias correction and the decrease in noise caused by averaging in the registered highres1 image. The highres.nii.gz image is then ready for use in FreeSurfer.

FreeSurfer Cortical Reconstruction

FreeSurfer is a widely used program that takes a high-resolution (typically 1mm isometric voxels) T1-weighted anatomical scan and estimates a 3D model of the cortical surface. In addition, it automatically divides the cortical surface and subcortical areas into anatomical subregions.

First, load the modules that are needed for FreeSurfer:

module load matlab
module load freesurfer/6.0.0

To run a standard FreeSurfer reconstruction, you can use run_freesurfer.sh, which calls the FreeSurfer script recon-all. To run one subject, you could run something like:

run_freesurfer.sh bender_03 12

This runs recon-all using the highres.nii.gz image in the anatomy directory of bender_03, and saves out results to $STUDYDIR/bender_03/anatomy/bender_03 by default, though this can be changed using the -o option. The second input argument is the number of threads to use. The way processing is run in parallel varies somewhat by version (FreeSurfer 6.0.0 runs more things in parallel than older versions). Brain hemispheres will be processed in parallel for some operations, and processing of each hemisphere will use the indicated number of threads. So 12 threads is a reasonable option to use all 24 cores on a Lonestar 5 compute node.

FreeSurfer takes several hours to complete, so we'll need to submit a job to run it. Because it will take longer than two hours to complete, we need to use the normal partition in this case (that is the default if the -p option is not specified). To submit a job to run both participants in parallel (this time with one node for each, to maximize the number of cores per subject), enter:

slaunch "run_freesurfer.sh {} 12" bender_03:bender_04 -N 2 -n 2 -r 08:00:00

You may also want to use the -m flag (put at the end, with the other launch options) to indicate an email address to notify when the job is complete.

Viewing FreeSurfer Images

FreeSurfer comes with a very good image and surface viewer, FreeView. To open it, in an idev session:

module load swr
freeview &

This will launch the application. Note that, in addition to the modules we loaded earlier, you also need to have the swr module loaded to use FreeView. Currently, swr is not installed on Lonestar 6. However, you can run FreeView using a remote desktop.

Try File>Load Volume and selecting $STUDYDIR/bender_03/anatomy/bender_03/mri/brain.finalsurfs.mgz and then File>Load Surface and selecting lh.pial, to see both the T1 scan and the estimated cortical surface for the left hemisphere.

Some of the FreeSurfer-related modules (mainly matlab, I think) can interfere with the operation of other modules, so I tend to not have them loaded by default. You can use module unload to unload the modules after you are finished using FreeSurfer and FreeView.

Converting FreeSurfer Output

FreeSurfer uses special formats for its files, which are not compatible with FSL. Next, we'll run convert_freesurfer.py, which converts some important files to NIfTI and makes some convenient anatomical masks that will be useful later. It's simple to call. If your FreeSurfer job has finished, you can run it first with --dry-run to see what commands will be run:

convert_freesurfer.py bender_03 --dry-run

It first converts files to NIfTI, then creates mask images (i.e. 1 for included voxels and 0 for everything else) for the brain, cortex, and white matter. To run it, you can use the virtual login node or an idev session (it's pretty quick):

convert_freesurfer.py bender_03
convert_freesurfer.py bender_04

Try taking a look at orig.nii.gz, brainmask.nii.gz, ctx.nii.gz, and wm.nii.gz (in each subject's anatomy directory) in fslview. If FreeSurfer hasn't finished yet, you can see these images in /corral-repl/utexas/prestonlab/preproc/part5/bender_03/anatomy.

Transforming FreeSurfer Results to Both Days

Finally, it will be useful to have the FreeSurfer results, including the masks we just made, in the same space as the two original highres scans. Due to differences in distortion, these scans aren't necessarily exactly the same shape. For the next step, unwarping of the functional data, we'll use the scan collected on the same day as the functional run to do the unwarping.

Again, use --dry-run to see what commands will be run, for one subject:

reg_freesurfer.py bender_03 --dry-run

The script calculates a linear transformation between the FreeSurfer output image, called orig.nii.gz, and the average highres image, highres.nii.gz. It then applies nonlinear transformations that were calculated before to move the FreeSurfer image into the spaces of the original highres scans. It does this for each of the outputs from FreeSurfer, as well as the masks we created in the previous step. Note that for continuously valued data, we use spline interpolation to calculate the final, transformed images. In contrast, for the masks, which have discrete values, we use nearest-neighbor interpolation. Otherwise, we would end up with a mask that had values other than 0 or 1, which is not what we want.

We've already calculated most of the transformations necessary to do this, so it won't take too long.

slaunch "reg_freesurfer.py {}" bender_03:bender_04 -N 1 -n 2 -a 12 -r 00:05:00 -p development

Now that we have prepped our anatomical data, we're finally ready to finish preprocessing of the BOLD data.