You can skip this first paragraph if you do not want to read a personal aside. One useful thing about becoming familiar with the command line interface (Terminal in OS X) is that a little scripting can save you days worth of work. I spent about 8 hours writing and modifying my first real bash script (I’ve played around a bit before with scripting but I hadn’t written anything particularly useful). I am not a programmer. I used to write some programs in TI-Basic on my TI calculators in High School and I took a C++ programming course in high school but I was never particularly good at programming. I started out as an electrical engineering major in college and took another programming course (Java) but I learned almost nothing in the course (our professor taught us a lot of things, I just didn’t learn anything). Again, I am not a programmer; my background in college is psychology. My focus now is on neuropsychology and neuroimaging. /End of personal story
In order to really move neuroimaging along it is beneficial to learn bash scripting. If you have no experience with bash and bash scripting, the Internet has a lot of great resources to start learning. One useful intro, especially for neuroimaging is FMRIB’s introduction to shell scripting. I learned much of the basics of scripting from that site. [I have to add here that I only know the basics of scripting; after all, I’ve only written one script]. My background is with bash so I won’t focus on any of the other shell and scripting environments (although they can be more powerful).
I use scripting because it saves me a lot of time. Plus I can better keep track of where I am in a processing stream. For example, let’s look at a portion of a processing stream for preparing diffusion weighted MRI scans for fiber tracking.
Images DICOMS >> NiFTI >> motion (eddy current) correction >> skull stripping >> co-registration with FreeSurfer processed T1 scans >> and so forth. If you have a lot of time or a lot of trained undergraduates you can move through this whole processing stream (and that was just a small portion of my processing stream!) step by step and manually for each research participant. That takes a lot of time and organization. Neuroimaging requires a lot of time and organization but you can only do so much before your brain implodes! Scripting is a useful way to keep the process organized and cut down on redundant tasks.
I like to write my scripts using Xcode, Apple’s built in programming environment. All you really need is a simple text editor but Xcode has some nice features and is easy to use. Now for scripting.
Every Bash script must start with the following:
#! /bin/sh
After that you can do whatever you need to do.
Placing a “#” (without the parentheses) at the beginning of a line comments out the whole line (makes it non-functional). This is a good way to explain what you are doing in the script so if you go and edit the script or if someone else does, it is obvious what you were doing.
Let’s have a sample script now that will convert a bunch of brains from FreeSurfer into Niftis, skull strip them, and then register them to preexisting diffusion scans.
#! /bin/sh
#Created by Jared Tanner on 08/03/2010
#Some other comment
cd /Applications/freesurfer/subjects
ls >> blindnums.txt
open -a TextEdit blindnums.txt
read -p “Now opening TextEdit to verify the subjects you want to convert. Press Enter to continue once you have finished verifying and editing the list.” shlock ;
echo Now making target directories and starting the conversion to NIfTI…
echo
for blind in `cat blindnums.txt` ; do
mkdir /Users/Shared/mri_images/${blind} ;
mri_convert ./${blind}/rawavg.mgz /Users/Shared/mri_images/${blind}/${blind}_rawavg.nii.gz ;
done
read -p “Now done converting to NIfTIs. Press Enter to continue…” shlock
cd /Users/Shared/mri_images
ls >> blindnums.txt
for blind in `cat blindnums.txt` ; do
echo Now converting ${blind}
echo
bet ./${blind}/${blind}_rawavg ./${blind}/${blind}_rawavg_brain -m -R -f .30 ;
done
echo Now FLIRTing…
for blind in `cat blindnums.txt` ; do
cp /Users/Shared/diffusion/${blind}/${blind}_nodif_brain.nii.gz ./${blind}/${blind}_nodif_brain.nii.gz
echo FLIRTing ${blind}…
echo
flirt -in $./${blind}/${blind}_rawavg_brain.nii.gz -ref ./${blind}/${blind}_nodif_brain.nii.gz -out ./${blind}/${blind}_rawavg_brain_nodif_trilinear.nii.gz -omat ./${blind}/${blind}_rawavg_brain_nodif_trilinear.mat -bins 256 -cost corratio -dof 12 ;
done
echo All done! Exiting script.
exit 0
That’s a very simple script that I just wrote in about 10 minutes. I’ll explain a few of the commands.
cp = copy [initial location] [target location]
cd = change directories
ls = list (contents of directory)
>> outputs text to a text file. An alternative is to do something like this: ls | tee -a blindnums.txt
echo = print to screen.
mkdir = make directory
for … ; do …. ; done – I’ll have to explain this some other time but for loops are very useful.
The script I wrote above is simple. It doesn’t have any error checks in it. It is a good idea to include things that will either not duplicate past efforts (say you already skull stripped some brains but the script processing was interrupted and there was more script to do, you could write an if-then command to check for a file and if it exists to go on to the next step, else it will create the missing file) or allow you to loop back and redo something if it didn’t work.
I’ll go into more about scripting later but I believe that neuroimaging work suffers without scripting knowledge. The best way to learn scripting is to read resources online and then just give it a try. Here are a few things to do:
- Always name files and folders consistently; if you don’t it’s a pain to deal with image processing
- Store files in easy to reach locations (/home/images/ is way better than /My \Stuff/Snacks/Chips/Brains/images/Freds \work/penguins/flamingfireballs) – keep things simple
- Search the web for help – the solution to your problem is out there
See below for a snippet of the script I recently wrote.